CobClient с TEvhttpClientChannel получает ошибку подтверждения при выполнении! FinishQueue.empty () в TEvhttpClientChannel :: finish - PullRequest
0 голосов
/ 01 мая 2020

Что я делаю

Я запускаю клиент thrift cob (сгенерированный сервис класс CobClient), используя TEvhttpClientChannel. У меня есть event_base_l oop () в одном потоке и вызов метода RP C в другом потоке (основной поток). Я использую канал обещания-будущего между обратным вызовом и основным потоком, чтобы уведомить, когда ответ получен. Примерно так:


static void RPCMethod_clientReturn(event_base* base, std::promise<int> * prom,
                                   Response * res  , MyCobClient* client){
    try{
    client->recv_RPCMethod(*res);
    prom->set_value(1);
    }
    catch(TException& e) {

        std::cout << "Exception in thrift client: " << e.what() << std::endl;
        prom->set_value(0);
    }
}

int main() {
  evthread_use_pthreads();
  event_enable_debug_logging(EVENT_DBG_ALL);
  struct event_base * base = event_base_new();
  std::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
  std::shared_ptr<TAsyncChannel> channel(
       new TEvhttpClientChannel(server.c_str(), "/", server.c_str(), port, base));
  // THE CLIENT
  MyCobClient* client = 
        new MyCobClient(channel, protocolFactory.get());

  // RUN THE EVENT LOOP IN SEPARATE THREAD
  std::thread event_thread = std::thread(&event_base_loop, base, EVLOOP_NO_EXIT_ON_EMPTY); 

  // INVOKE RPCMethod. Wait for response before invoking next RPCMethod.
  for(int i; i < REQS; i++){
    std::promise<int> prom;
    Request req;
    Response res;
    auto fut = prom.get_future();
    //MAKE THE RPC CALL
    client->RPCMethod(std::bind(RPCMethod_clientReturn,
                                base,&prom,&res,
                                std::placeholders::_1),
                               req);
    // WAIT FOR CALLBACK TO SET THE PROMISE (i.e. WAIT FOR RESPONSE)
    fut.wait();
    if (fut.get() == 0){
      std::cout << "Error..." << std::endl;
    }
  }
}

К моей проблеме

Я получаю ошибку подтверждения при выполнении !ningQueue.empty () в TEvhttpClientChannel :: fini sh. Отладочная информация, которая выводится до появления ошибки здесь .

Надеюсь, есть кто-то, кто сталкивался с подобной проблемой раньше. Я попытался просмотреть исходный код, и единственная возможность, которую я вижу для этого, находится в TEvhttpClientChannel. cpp: 85 и TEvhttpClientChannel. cpp: 90 , что основной поток вытесняется после строки 85 (запрос make / register), но до строки 90 (pu sh toquequeueue), а поток event_l oop завершает событие и попадает в TEvhttpClientChannel :: fini sh (утверждает очередь завершения не пустая и тянет из очереди завершения) до того, как основной поток доберется до pu sh до очереди завершения в строке 90. Просто дикое предположение, что ... Вы действительно не знаете, как я мог это проверить .. Возможно, GDB? Возможно, TEvhttpClientChannel принципиально не предназначен для запуска события l oop в отдельном потоке?

...