blob: fa6bff5889a7693f9888678017cd0f64af81076e [file] [log] [blame]
David Reissea2cba82009-03-30 21:35:00 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
Mark Slee9f0c6512007-02-28 23:58:26 +000019
Roger Meier49ff8b12012-04-13 09:12:31 +000020#include <thrift/server/TSimpleServer.h>
21#include <thrift/transport/TTransportException.h>
Mark Sleee8540632006-05-30 09:24:40 +000022#include <string>
Mark Slee8d7e1f62006-06-07 06:48:56 +000023#include <iostream>
Mark Sleee8540632006-05-30 09:24:40 +000024
Konrad Grochowski16a23a62014-11-13 15:33:38 +010025namespace apache {
26namespace thrift {
27namespace server {
Marc Slemko6f038a72006-08-03 18:58:09 +000028
Mark Slee5ea15f92007-03-05 22:55:59 +000029using namespace std;
T Jake Lucianib5e62212009-01-31 22:36:20 +000030using namespace apache::thrift;
31using namespace apache::thrift::protocol;
32using namespace apache::thrift::transport;
Mark Slee5ea15f92007-03-05 22:55:59 +000033using boost::shared_ptr;
34
Mark Slee8d7e1f62006-06-07 06:48:56 +000035/**
36 * A simple single-threaded application server. Perfect for unit tests!
37 *
Mark Slee8d7e1f62006-06-07 06:48:56 +000038 */
Mark Slee794993d2006-09-20 01:56:10 +000039void TSimpleServer::serve() {
Marc Slemko16698852006-08-04 03:16:10 +000040
41 shared_ptr<TTransport> client;
Aditya Agarwal9abb0d62007-01-24 22:53:54 +000042 shared_ptr<TTransport> inputTransport;
43 shared_ptr<TTransport> outputTransport;
44 shared_ptr<TProtocol> inputProtocol;
45 shared_ptr<TProtocol> outputProtocol;
Mark Sleee8540632006-05-30 09:24:40 +000046
Roger Meierd8f50f32012-04-11 21:48:56 +000047 // Start the server listening
48 serverTransport_->listen();
Mark Sleee8540632006-05-30 09:24:40 +000049
Mark Sleeb4d3e7b2007-11-28 01:51:43 +000050 // Run the preServe event
Roger Meier72957452013-06-29 00:28:50 +020051 if (eventHandler_) {
Mark Sleeb4d3e7b2007-11-28 01:51:43 +000052 eventHandler_->preServe();
53 }
54
Mark Sleee8540632006-05-30 09:24:40 +000055 // Fetch client from server
Mark Slee6e3f6372007-03-01 22:05:46 +000056 while (!stop_) {
Aditya Agarwalfdef47e2007-02-07 03:54:18 +000057 try {
Mark Slee8d7e1f62006-06-07 06:48:56 +000058 client = serverTransport_->accept();
Aditya Agarwal9abb0d62007-01-24 22:53:54 +000059 inputTransport = inputTransportFactory_->getTransport(client);
60 outputTransport = outputTransportFactory_->getTransport(client);
61 inputProtocol = inputProtocolFactory_->getProtocol(inputTransport);
62 outputProtocol = outputProtocolFactory_->getProtocol(outputTransport);
Aditya Agarwalfdef47e2007-02-07 03:54:18 +000063 } catch (TTransportException& ttx) {
Konrad Grochowski16a23a62014-11-13 15:33:38 +010064 if (inputTransport) {
65 inputTransport->close();
66 }
67 if (outputTransport) {
68 outputTransport->close();
69 }
70 if (client) {
71 client->close();
72 }
Jake Farrell6ce27042012-01-27 04:32:17 +000073 if (!stop_ || ttx.getType() != TTransportException::INTERRUPTED) {
Konrad Grochowski16a23a62014-11-13 15:33:38 +010074 string errStr = string("TServerTransport died on accept: ") + ttx.what();
75 GlobalOutput(errStr.c_str());
Jake Farrell6ce27042012-01-27 04:32:17 +000076 }
Aditya Agarwalfdef47e2007-02-07 03:54:18 +000077 continue;
78 } catch (TException& tx) {
Konrad Grochowski16a23a62014-11-13 15:33:38 +010079 if (inputTransport) {
80 inputTransport->close();
81 }
82 if (outputTransport) {
83 outputTransport->close();
84 }
85 if (client) {
86 client->close();
87 }
David Reiss25df8e72010-10-06 17:10:54 +000088 string errStr = string("Some kind of accept exception: ") + tx.what();
89 GlobalOutput(errStr.c_str());
Aditya Agarwalfdef47e2007-02-07 03:54:18 +000090 continue;
91 } catch (string s) {
Konrad Grochowski16a23a62014-11-13 15:33:38 +010092 if (inputTransport) {
93 inputTransport->close();
94 }
95 if (outputTransport) {
96 outputTransport->close();
97 }
98 if (client) {
99 client->close();
100 }
David Reiss25df8e72010-10-06 17:10:54 +0000101 string errStr = string("Some kind of accept exception: ") + s;
102 GlobalOutput(errStr.c_str());
Aditya Agarwalfdef47e2007-02-07 03:54:18 +0000103 break;
Mark Sleed788b2e2006-09-07 01:26:35 +0000104 }
David Reiss25df8e72010-10-06 17:10:54 +0000105
Bryan Duxbury6dd9cd02011-09-01 18:06:20 +0000106 // Get the processor
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100107 shared_ptr<TProcessor> processor = getProcessor(inputProtocol, outputProtocol, client);
Bryan Duxbury6dd9cd02011-09-01 18:06:20 +0000108
David Reiss25df8e72010-10-06 17:10:54 +0000109 void* connectionContext = NULL;
Roger Meier72957452013-06-29 00:28:50 +0200110 if (eventHandler_) {
David Reiss25df8e72010-10-06 17:10:54 +0000111 connectionContext = eventHandler_->createContext(inputProtocol, outputProtocol);
112 }
113 try {
114 for (;;) {
Roger Meier72957452013-06-29 00:28:50 +0200115 if (eventHandler_) {
David Reiss25df8e72010-10-06 17:10:54 +0000116 eventHandler_->processContext(connectionContext, client);
117 }
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100118 if (!processor->process(inputProtocol, outputProtocol, connectionContext) ||
119 // Peek ahead, is the remote side closed?
David Reiss25df8e72010-10-06 17:10:54 +0000120 !inputProtocol->getTransport()->peek()) {
121 break;
122 }
123 }
Bryan Duxbury1e987582011-08-25 17:33:03 +0000124 } catch (const TTransportException& ttx) {
David Reiss25df8e72010-10-06 17:10:54 +0000125 string errStr = string("TSimpleServer client died: ") + ttx.what();
126 GlobalOutput(errStr.c_str());
Bryan Duxbury1e987582011-08-25 17:33:03 +0000127 } catch (const std::exception& x) {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100128 GlobalOutput.printf("TSimpleServer exception: %s: %s", typeid(x).name(), x.what());
David Reiss25df8e72010-10-06 17:10:54 +0000129 } catch (...) {
130 GlobalOutput("TSimpleServer uncaught exception.");
131 }
Roger Meier72957452013-06-29 00:28:50 +0200132 if (eventHandler_) {
David Reiss25df8e72010-10-06 17:10:54 +0000133 eventHandler_->deleteContext(connectionContext, inputProtocol, outputProtocol);
134 }
135
136 try {
137 inputTransport->close();
Bryan Duxburye04159c2011-08-25 17:43:56 +0000138 } catch (const TTransportException& ttx) {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100139 string errStr = string("TSimpleServer input close failed: ") + ttx.what();
David Reiss25df8e72010-10-06 17:10:54 +0000140 GlobalOutput(errStr.c_str());
141 }
142 try {
143 outputTransport->close();
Bryan Duxburye04159c2011-08-25 17:43:56 +0000144 } catch (const TTransportException& ttx) {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100145 string errStr = string("TSimpleServer output close failed: ") + ttx.what();
David Reiss25df8e72010-10-06 17:10:54 +0000146 GlobalOutput(errStr.c_str());
147 }
148 try {
149 client->close();
Bryan Duxburye04159c2011-08-25 17:43:56 +0000150 } catch (const TTransportException& ttx) {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100151 string errStr = string("TSimpleServer client close failed: ") + ttx.what();
David Reiss25df8e72010-10-06 17:10:54 +0000152 GlobalOutput(errStr.c_str());
153 }
Mark Sleee8540632006-05-30 09:24:40 +0000154 }
155
Mark Slee6e3f6372007-03-01 22:05:46 +0000156 if (stop_) {
157 try {
158 serverTransport_->close();
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100159 } catch (TTransportException& ttx) {
David Reiss25df8e72010-10-06 17:10:54 +0000160 string errStr = string("TServerTransport failed on close: ") + ttx.what();
161 GlobalOutput(errStr.c_str());
Mark Slee6e3f6372007-03-01 22:05:46 +0000162 }
163 stop_ = false;
164 }
Mark Sleee8540632006-05-30 09:24:40 +0000165}
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100166}
167}
168} // apache::thrift::server