blob: d77e4230ef5f62617efe4fdee3b38e15b8e10951 [file] [log] [blame]
Mark Slee9f0c6512007-02-28 23:58:26 +00001// Copyright (c) 2006- Facebook
2// Distributed under the Thrift Software License
3//
4// See accompanying file LICENSE or visit the Thrift site at:
5// http://developers.facebook.com/thrift/
6
Mark Sleee8540632006-05-30 09:24:40 +00007#include "server/TSimpleServer.h"
Mark Slee8d7e1f62006-06-07 06:48:56 +00008#include "transport/TTransportException.h"
Mark Sleee8540632006-05-30 09:24:40 +00009#include <string>
Mark Slee8d7e1f62006-06-07 06:48:56 +000010#include <iostream>
Mark Sleee8540632006-05-30 09:24:40 +000011
T Jake Lucianib5e62212009-01-31 22:36:20 +000012namespace apache { namespace thrift { namespace server {
Marc Slemko6f038a72006-08-03 18:58:09 +000013
Mark Slee5ea15f92007-03-05 22:55:59 +000014using namespace std;
T Jake Lucianib5e62212009-01-31 22:36:20 +000015using namespace apache::thrift;
16using namespace apache::thrift::protocol;
17using namespace apache::thrift::transport;
Mark Slee5ea15f92007-03-05 22:55:59 +000018using boost::shared_ptr;
19
Mark Slee8d7e1f62006-06-07 06:48:56 +000020/**
21 * A simple single-threaded application server. Perfect for unit tests!
22 *
Mark Slee8d7e1f62006-06-07 06:48:56 +000023 */
Mark Slee794993d2006-09-20 01:56:10 +000024void TSimpleServer::serve() {
Marc Slemko16698852006-08-04 03:16:10 +000025
26 shared_ptr<TTransport> client;
Aditya Agarwal9abb0d62007-01-24 22:53:54 +000027 shared_ptr<TTransport> inputTransport;
28 shared_ptr<TTransport> outputTransport;
29 shared_ptr<TProtocol> inputProtocol;
30 shared_ptr<TProtocol> outputProtocol;
Mark Sleee8540632006-05-30 09:24:40 +000031
Mark Slee8d7e1f62006-06-07 06:48:56 +000032 try {
33 // Start the server listening
34 serverTransport_->listen();
35 } catch (TTransportException& ttx) {
Mark Sleeb9ff32a2006-11-16 01:00:24 +000036 cerr << "TSimpleServer::run() listen(): " << ttx.what() << endl;
Mark Sleee8540632006-05-30 09:24:40 +000037 return;
38 }
39
Mark Sleeb4d3e7b2007-11-28 01:51:43 +000040 // Run the preServe event
41 if (eventHandler_ != NULL) {
42 eventHandler_->preServe();
43 }
44
Mark Sleee8540632006-05-30 09:24:40 +000045 // Fetch client from server
Mark Slee6e3f6372007-03-01 22:05:46 +000046 while (!stop_) {
Aditya Agarwalfdef47e2007-02-07 03:54:18 +000047 try {
Mark Slee8d7e1f62006-06-07 06:48:56 +000048 client = serverTransport_->accept();
Aditya Agarwal9abb0d62007-01-24 22:53:54 +000049 inputTransport = inputTransportFactory_->getTransport(client);
50 outputTransport = outputTransportFactory_->getTransport(client);
51 inputProtocol = inputProtocolFactory_->getProtocol(inputTransport);
52 outputProtocol = outputProtocolFactory_->getProtocol(outputTransport);
Mark Sleeb4d3e7b2007-11-28 01:51:43 +000053 if (eventHandler_ != NULL) {
54 eventHandler_->clientBegin(inputProtocol, outputProtocol);
55 }
Mark Sleed788b2e2006-09-07 01:26:35 +000056 try {
Aditya Agarwal9abb0d62007-01-24 22:53:54 +000057 while (processor_->process(inputProtocol, outputProtocol)) {
Mark Sleeb9ff32a2006-11-16 01:00:24 +000058 // Peek ahead, is the remote side closed?
Aditya Agarwal9abb0d62007-01-24 22:53:54 +000059 if (!inputTransport->peek()) {
Mark Sleeb9ff32a2006-11-16 01:00:24 +000060 break;
61 }
62 }
Mark Sleed788b2e2006-09-07 01:26:35 +000063 } catch (TTransportException& ttx) {
Mark Sleeb9ff32a2006-11-16 01:00:24 +000064 cerr << "TSimpleServer client died: " << ttx.what() << endl;
Mark Slee3860c9a2006-12-06 00:13:42 +000065 } catch (TException& tx) {
66 cerr << "TSimpleServer exception: " << tx.what() << endl;
Mark Sleee8540632006-05-30 09:24:40 +000067 }
Mark Sleeb4d3e7b2007-11-28 01:51:43 +000068 if (eventHandler_ != NULL) {
69 eventHandler_->clientEnd(inputProtocol, outputProtocol);
70 }
Aditya Agarwal9abb0d62007-01-24 22:53:54 +000071 inputTransport->close();
72 outputTransport->close();
Mark Sleeb4d3e7b2007-11-28 01:51:43 +000073 client->close();
Aditya Agarwalfdef47e2007-02-07 03:54:18 +000074 } catch (TTransportException& ttx) {
Mark Slee3303f362007-03-05 20:09:37 +000075 if (inputTransport != NULL) { inputTransport->close(); }
76 if (outputTransport != NULL) { outputTransport->close(); }
77 if (client != NULL) { client->close(); }
Aditya Agarwalfdef47e2007-02-07 03:54:18 +000078 cerr << "TServerTransport died on accept: " << ttx.what() << endl;
79 continue;
80 } catch (TException& tx) {
Mark Slee3303f362007-03-05 20:09:37 +000081 if (inputTransport != NULL) { inputTransport->close(); }
82 if (outputTransport != NULL) { outputTransport->close(); }
83 if (client != NULL) { client->close(); }
Aditya Agarwalfdef47e2007-02-07 03:54:18 +000084 cerr << "Some kind of accept exception: " << tx.what() << endl;
85 continue;
86 } catch (string s) {
Mark Slee3303f362007-03-05 20:09:37 +000087 if (inputTransport != NULL) { inputTransport->close(); }
88 if (outputTransport != NULL) { outputTransport->close(); }
89 if (client != NULL) { client->close(); }
Aditya Agarwalfdef47e2007-02-07 03:54:18 +000090 cerr << "TThreadPoolServer: Unknown exception: " << s << endl;
91 break;
Mark Sleed788b2e2006-09-07 01:26:35 +000092 }
Mark Sleee8540632006-05-30 09:24:40 +000093 }
94
Mark Slee6e3f6372007-03-01 22:05:46 +000095 if (stop_) {
96 try {
97 serverTransport_->close();
98 } catch (TTransportException &ttx) {
99 cerr << "TServerTransport failed on close: " << ttx.what() << endl;
100 }
101 stop_ = false;
102 }
Mark Sleee8540632006-05-30 09:24:40 +0000103}
Marc Slemko6f038a72006-08-03 18:58:09 +0000104
T Jake Lucianib5e62212009-01-31 22:36:20 +0000105}}} // apache::thrift::server