2015-08-18 2 views
1

Я использую Apache Thrift TSimpleServer в моих проектах на C++. После запуска сервер будет прослушивать запросы на подключение и обработку клиентов. Все в порядке, но иногда сервер останавливался без каких-либо признаков.Где находится выход Apache Thrift C++ GlobalOutput?

Я следую за источником благотворительной библиотеки и вижу, что GlobalOutput(error_message) создается, когда TTransportException или TException пойманы. Мне нужно понять это, чтобы создать механизм восстановления, когда сервер умирает.

Вот исходный код, я говорю:

void TSimpleServer::serve() { 

    shared_ptr<TTransport> client; 
    shared_ptr<TTransport> inputTransport; 
    shared_ptr<TTransport> outputTransport; 
    shared_ptr<TProtocol> inputProtocol; 
    shared_ptr<TProtocol> outputProtocol; 

    // Start the server listening 
    serverTransport_->listen(); 

    // Run the preServe event 
    if (eventHandler_) { 
    eventHandler_->preServe(); 
    } 

    // Fetch client from server 
    while (!stop_) { 
    try { 
     client = serverTransport_->accept(); 
     inputTransport = inputTransportFactory_->getTransport(client); 
     outputTransport = outputTransportFactory_->getTransport(client); 
     inputProtocol = inputProtocolFactory_->getProtocol(inputTransport); 
     outputProtocol = outputProtocolFactory_->getProtocol(outputTransport); 
    } catch (TTransportException& ttx) { 
     if (inputTransport) { inputTransport->close(); } 
     if (outputTransport) { outputTransport->close(); } 
     if (client) { client->close(); } 
     if (!stop_ || ttx.getType() != TTransportException::INTERRUPTED) { 
      string errStr = string("TServerTransport died on accept: ") + ttx.what(); 
      GlobalOutput(errStr.c_str()); 
     } 
     continue; 
    } catch (TException& tx) { 
     if (inputTransport) { inputTransport->close(); } 
     if (outputTransport) { outputTransport->close(); } 
     if (client) { client->close(); } 
     string errStr = string("Some kind of accept exception: ") + tx.what(); 
     GlobalOutput(errStr.c_str()); 
     continue; 
    } catch (string s) { 
     if (inputTransport) { inputTransport->close(); } 
     if (outputTransport) { outputTransport->close(); } 
     if (client) { client->close(); } 
     string errStr = string("Some kind of accept exception: ") + s; 
     GlobalOutput(errStr.c_str()); 
     break; 
    } 

    // Get the processor 
    shared_ptr<TProcessor> processor = getProcessor(inputProtocol, 
                outputProtocol, client); 

    void* connectionContext = NULL; 
    if (eventHandler_) { 
     connectionContext = eventHandler_->createContext(inputProtocol, outputProtocol); 
    } 
    try { 
     for (;;) { 
     if (eventHandler_) { 
      eventHandler_->processContext(connectionContext, client); 
     } 
     if (!processor->process(inputProtocol, outputProtocol, 
           connectionContext) || 
      // Peek ahead, is the remote side closed? 
      !inputProtocol->getTransport()->peek()) { 
      break; 
     } 
     } 
    } catch (const TTransportException& ttx) { 
     string errStr = string("TSimpleServer client died: ") + ttx.what(); 
     GlobalOutput(errStr.c_str()); 
    } catch (const std::exception& x) { 
     GlobalOutput.printf("TSimpleServer exception: %s: %s", 
          typeid(x).name(), x.what()); 
    } catch (...) { 
     GlobalOutput("TSimpleServer uncaught exception."); 
    } 
    if (eventHandler_) { 
     eventHandler_->deleteContext(connectionContext, inputProtocol, outputProtocol); 
    } 

    try { 
     inputTransport->close(); 
    } catch (const TTransportException& ttx) { 
     string errStr = string("TSimpleServer input close failed: ") 
     + ttx.what(); 
     GlobalOutput(errStr.c_str()); 
    } 
    try { 
     outputTransport->close(); 
    } catch (const TTransportException& ttx) { 
     string errStr = string("TSimpleServer output close failed: ") 
     + ttx.what(); 
     GlobalOutput(errStr.c_str()); 
    } 
    try { 
     client->close(); 
    } catch (const TTransportException& ttx) { 
     string errStr = string("TSimpleServer client close failed: ") 
     + ttx.what(); 
     GlobalOutput(errStr.c_str()); 
    } 
    } 

    if (stop_) { 
    try { 
     serverTransport_->close(); 
    } catch (TTransportException &ttx) { 
     string errStr = string("TServerTransport failed on close: ") + ttx.what(); 
     GlobalOutput(errStr.c_str()); 
    } 
    stop_ = false; 
    } 
} 

ответ

0

Глубоко внутри TOutput.cpp есть линия fprintf(stderr, "Thrift: %s %s\n", dbgtime, msg);(source here) и что там по умолчанию все сообщения Бережливость GlobalOutput в конечном итоге (в стандартной ошибки).

Но вы можете изменить его (если по какой-либо причине вы не можете использовать стандартный поток ошибок), предоставляя собственный обработчик GlobalOutput в виде указателя функции:

void myOutputFunction(const char* x) 
{ 
    fprintf(myLogFile, "Thrift internal message: %s\n", x); 
} 

// Inside some init function or main 
GlobalOutput.setOutputFunction(myOutputFunction); 
+0

спасибо за ответ и ссылку на источник. Сценарий 0.9.2, который я загрузил из [здесь] (http://www.apache.org/dyn/closer.cgi?path=/thrift/0.9.2/thrift-0.9.2.tar.gz), не содержат TOutput.cpp (и TOutput.h). Но ссылка источника, которую вы предложили, имеет это. Являются ли эти источники совместимыми и могу ли я просто скопировать TOutput.cpp и .h в свой проект и использовать их? – simon

+0

TOutput.xxx был извлечен недавно, в 0.9.2 аналогичный код должен быть внутри Thrift.h и Thrift.cpp – Hcorg

+0

Найденный. Большое спасибо. – simon

Смежные вопросы