1 /* 2 * Copyright (c) 2006- Facebook 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 /* 7 * Licensed to the Apache Software Foundation (ASF) under one 8 * or more contributor license agreements. See the NOTICE file 9 * distributed with this work for additional information 10 * regarding copyright ownership. The ASF licenses this file 11 * to you under the Apache License, Version 2.0 (the 12 * "License"); you may not use this file except in compliance 13 * with the License. You may obtain a copy of the License at 14 * 15 * http://www.apache.org/licenses/LICENSE-2.0 16 * 17 * Unless required by applicable law or agreed to in writing, 18 * software distributed under the License is distributed on an 19 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 20 * KIND, either express or implied. See the License for the 21 * specific language governing permissions and limitations 22 * under the License. 23 */ 24 25 #ifndef _THRIFT_SERVER_TSERVER_H_ 26 #define _THRIFT_SERVER_TSERVER_H_ 1 27 28 #include <thrift/TProcessor.h> 29 #include <thrift/protocol/TBinaryProtocol.h> 30 #include <thrift/transport/TServerTransport.h> 31 32 #include <memory> 33 34 namespace apache 35 { 36 namespace thrift 37 { 38 namespace server 39 { 40 41 using apache::thrift::TProcessor; 42 using apache::thrift::protocol::TBinaryProtocolFactory; 43 using apache::thrift::protocol::TProtocol; 44 using apache::thrift::protocol::TProtocolFactory; 45 using apache::thrift::transport::TServerTransport; 46 using apache::thrift::transport::TTransport; 47 using apache::thrift::transport::TTransportFactory; 48 49 /** 50 * Virtual interface class that can handle events from the server core. To 51 * use this you should subclass it and implement the methods that you care 52 * about. Your subclass can also store local data that you may care about, 53 * such as additional "arguments" to these methods (stored in the object 54 * instance's state). 55 */ 56 class TServerEventHandler 57 { 58 public: 59 virtual ~TServerEventHandler() = default; 60 61 /** 62 * Called before the server begins. 63 */ preServe()64 virtual void preServe() 65 { 66 } 67 68 /** 69 * Called when a new client has connected and is about to being processing. 70 */ createContext(std::shared_ptr<TProtocol> input,std::shared_ptr<TProtocol> output)71 virtual void *createContext(std::shared_ptr<TProtocol> input, 72 std::shared_ptr<TProtocol> output) 73 { 74 (void)input; 75 (void)output; 76 return nullptr; 77 } 78 79 /** 80 * Called when a client has finished request-handling to delete server 81 * context. 82 */ deleteContext(void * serverContext,std::shared_ptr<TProtocol> input,std::shared_ptr<TProtocol> output)83 virtual void deleteContext(void *serverContext, std::shared_ptr<TProtocol> input, 84 std::shared_ptr<TProtocol> output) 85 { 86 (void)serverContext; 87 (void)input; 88 (void)output; 89 } 90 91 /** 92 * Called when a client is about to call the processor. 93 */ processContext(void * serverContext,std::shared_ptr<TTransport> transport)94 virtual void processContext(void *serverContext, std::shared_ptr<TTransport> transport) 95 { 96 (void)serverContext; 97 (void)transport; 98 } 99 100 protected: 101 /** 102 * Prevent direct instantiation. 103 */ 104 TServerEventHandler() = default; 105 }; 106 107 /** 108 * Thrift server. 109 * 110 */ 111 class TServer 112 { 113 public: 114 ~TServer() = default; 115 116 virtual void serve() = 0; 117 stop()118 virtual void stop() 119 { 120 } 121 122 // Allows running the server as a Runnable thread run()123 void run() 124 { 125 serve(); 126 } 127 getProcessorFactory()128 std::shared_ptr<TProcessorFactory> getProcessorFactory() 129 { 130 return processorFactory_; 131 } 132 getServerTransport()133 std::shared_ptr<TServerTransport> getServerTransport() 134 { 135 return serverTransport_; 136 } 137 getInputTransportFactory()138 std::shared_ptr<TTransportFactory> getInputTransportFactory() 139 { 140 return inputTransportFactory_; 141 } 142 getOutputTransportFactory()143 std::shared_ptr<TTransportFactory> getOutputTransportFactory() 144 { 145 return outputTransportFactory_; 146 } 147 getInputProtocolFactory()148 std::shared_ptr<TProtocolFactory> getInputProtocolFactory() 149 { 150 return inputProtocolFactory_; 151 } 152 getOutputProtocolFactory()153 std::shared_ptr<TProtocolFactory> getOutputProtocolFactory() 154 { 155 return outputProtocolFactory_; 156 } 157 getEventHandler()158 std::shared_ptr<TServerEventHandler> getEventHandler() 159 { 160 return eventHandler_; 161 } 162 163 protected: TServer(const std::shared_ptr<TProcessorFactory> & processorFactory)164 TServer(const std::shared_ptr<TProcessorFactory> &processorFactory) 165 : processorFactory_(processorFactory) 166 { 167 setInputTransportFactory( 168 std::shared_ptr<TTransportFactory>(new TTransportFactory())); 169 setOutputTransportFactory( 170 std::shared_ptr<TTransportFactory>(new TTransportFactory())); 171 setInputProtocolFactory( 172 std::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory())); 173 setOutputProtocolFactory( 174 std::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory())); 175 } 176 TServer(const std::shared_ptr<TProcessor> & processor)177 TServer(const std::shared_ptr<TProcessor> &processor) 178 : processorFactory_(new TSingletonProcessorFactory(processor)) 179 { 180 setInputTransportFactory( 181 std::shared_ptr<TTransportFactory>(new TTransportFactory())); 182 setOutputTransportFactory( 183 std::shared_ptr<TTransportFactory>(new TTransportFactory())); 184 setInputProtocolFactory( 185 std::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory())); 186 setOutputProtocolFactory( 187 std::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory())); 188 } 189 TServer(const std::shared_ptr<TProcessorFactory> & processorFactory,const std::shared_ptr<TServerTransport> & serverTransport)190 TServer(const std::shared_ptr<TProcessorFactory> &processorFactory, 191 const std::shared_ptr<TServerTransport> &serverTransport) 192 : processorFactory_(processorFactory), serverTransport_(serverTransport) 193 { 194 setInputTransportFactory( 195 std::shared_ptr<TTransportFactory>(new TTransportFactory())); 196 setOutputTransportFactory( 197 std::shared_ptr<TTransportFactory>(new TTransportFactory())); 198 setInputProtocolFactory( 199 std::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory())); 200 setOutputProtocolFactory( 201 std::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory())); 202 } 203 TServer(const std::shared_ptr<TProcessor> & processor,const std::shared_ptr<TServerTransport> & serverTransport)204 TServer(const std::shared_ptr<TProcessor> &processor, 205 const std::shared_ptr<TServerTransport> &serverTransport) 206 : processorFactory_(new TSingletonProcessorFactory(processor)), 207 serverTransport_(serverTransport) 208 { 209 setInputTransportFactory( 210 std::shared_ptr<TTransportFactory>(new TTransportFactory())); 211 setOutputTransportFactory( 212 std::shared_ptr<TTransportFactory>(new TTransportFactory())); 213 setInputProtocolFactory( 214 std::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory())); 215 setOutputProtocolFactory( 216 std::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory())); 217 } 218 TServer(const std::shared_ptr<TProcessorFactory> & processorFactory,const std::shared_ptr<TServerTransport> & serverTransport,const std::shared_ptr<TTransportFactory> & transportFactory,const std::shared_ptr<TProtocolFactory> & protocolFactory)219 TServer(const std::shared_ptr<TProcessorFactory> &processorFactory, 220 const std::shared_ptr<TServerTransport> &serverTransport, 221 const std::shared_ptr<TTransportFactory> &transportFactory, 222 const std::shared_ptr<TProtocolFactory> &protocolFactory) 223 : processorFactory_(processorFactory), serverTransport_(serverTransport), 224 inputTransportFactory_(transportFactory), 225 outputTransportFactory_(transportFactory), inputProtocolFactory_(protocolFactory), 226 outputProtocolFactory_(protocolFactory) 227 { 228 } 229 TServer(const std::shared_ptr<TProcessor> & processor,const std::shared_ptr<TServerTransport> & serverTransport,const std::shared_ptr<TTransportFactory> & transportFactory,const std::shared_ptr<TProtocolFactory> & protocolFactory)230 TServer(const std::shared_ptr<TProcessor> &processor, 231 const std::shared_ptr<TServerTransport> &serverTransport, 232 const std::shared_ptr<TTransportFactory> &transportFactory, 233 const std::shared_ptr<TProtocolFactory> &protocolFactory) 234 : processorFactory_(new TSingletonProcessorFactory(processor)), 235 serverTransport_(serverTransport), inputTransportFactory_(transportFactory), 236 outputTransportFactory_(transportFactory), inputProtocolFactory_(protocolFactory), 237 outputProtocolFactory_(protocolFactory) 238 { 239 } 240 TServer(const std::shared_ptr<TProcessorFactory> & processorFactory,const std::shared_ptr<TServerTransport> & serverTransport,const std::shared_ptr<TTransportFactory> & inputTransportFactory,const std::shared_ptr<TTransportFactory> & outputTransportFactory,const std::shared_ptr<TProtocolFactory> & inputProtocolFactory,const std::shared_ptr<TProtocolFactory> & outputProtocolFactory)241 TServer(const std::shared_ptr<TProcessorFactory> &processorFactory, 242 const std::shared_ptr<TServerTransport> &serverTransport, 243 const std::shared_ptr<TTransportFactory> &inputTransportFactory, 244 const std::shared_ptr<TTransportFactory> &outputTransportFactory, 245 const std::shared_ptr<TProtocolFactory> &inputProtocolFactory, 246 const std::shared_ptr<TProtocolFactory> &outputProtocolFactory) 247 : processorFactory_(processorFactory), serverTransport_(serverTransport), 248 inputTransportFactory_(inputTransportFactory), 249 outputTransportFactory_(outputTransportFactory), 250 inputProtocolFactory_(inputProtocolFactory), 251 outputProtocolFactory_(outputProtocolFactory) 252 { 253 } 254 TServer(const std::shared_ptr<TProcessor> & processor,const std::shared_ptr<TServerTransport> & serverTransport,const std::shared_ptr<TTransportFactory> & inputTransportFactory,const std::shared_ptr<TTransportFactory> & outputTransportFactory,const std::shared_ptr<TProtocolFactory> & inputProtocolFactory,const std::shared_ptr<TProtocolFactory> & outputProtocolFactory)255 TServer(const std::shared_ptr<TProcessor> &processor, 256 const std::shared_ptr<TServerTransport> &serverTransport, 257 const std::shared_ptr<TTransportFactory> &inputTransportFactory, 258 const std::shared_ptr<TTransportFactory> &outputTransportFactory, 259 const std::shared_ptr<TProtocolFactory> &inputProtocolFactory, 260 const std::shared_ptr<TProtocolFactory> &outputProtocolFactory) 261 : processorFactory_(new TSingletonProcessorFactory(processor)), 262 serverTransport_(serverTransport), inputTransportFactory_(inputTransportFactory), 263 outputTransportFactory_(outputTransportFactory), 264 inputProtocolFactory_(inputProtocolFactory), 265 outputProtocolFactory_(outputProtocolFactory) 266 { 267 } 268 269 /** 270 * Get a TProcessor to handle calls on a particular connection. 271 * 272 * This method should only be called once per connection (never once per 273 * call). This allows the TProcessorFactory to return a different processor 274 * for each connection if it desires. 275 */ getProcessor(std::shared_ptr<TProtocol> inputProtocol,std::shared_ptr<TProtocol> outputProtocol,std::shared_ptr<TTransport> transport)276 std::shared_ptr<TProcessor> getProcessor(std::shared_ptr<TProtocol> inputProtocol, 277 std::shared_ptr<TProtocol> outputProtocol, 278 std::shared_ptr<TTransport> transport) 279 { 280 TConnectionInfo connInfo; 281 connInfo.input = inputProtocol; 282 connInfo.output = outputProtocol; 283 connInfo.transport = transport; 284 return processorFactory_->getProcessor(connInfo); 285 } 286 287 // Class variables 288 std::shared_ptr<TProcessorFactory> processorFactory_; 289 std::shared_ptr<TServerTransport> serverTransport_; 290 291 std::shared_ptr<TTransportFactory> inputTransportFactory_; 292 std::shared_ptr<TTransportFactory> outputTransportFactory_; 293 294 std::shared_ptr<TProtocolFactory> inputProtocolFactory_; 295 std::shared_ptr<TProtocolFactory> outputProtocolFactory_; 296 297 std::shared_ptr<TServerEventHandler> eventHandler_; 298 299 public: setInputTransportFactory(std::shared_ptr<TTransportFactory> inputTransportFactory)300 void setInputTransportFactory(std::shared_ptr<TTransportFactory> inputTransportFactory) 301 { 302 inputTransportFactory_ = inputTransportFactory; 303 } 304 setOutputTransportFactory(std::shared_ptr<TTransportFactory> outputTransportFactory)305 void setOutputTransportFactory(std::shared_ptr<TTransportFactory> outputTransportFactory) 306 { 307 outputTransportFactory_ = outputTransportFactory; 308 } 309 setInputProtocolFactory(std::shared_ptr<TProtocolFactory> inputProtocolFactory)310 void setInputProtocolFactory(std::shared_ptr<TProtocolFactory> inputProtocolFactory) 311 { 312 inputProtocolFactory_ = inputProtocolFactory; 313 } 314 setOutputProtocolFactory(std::shared_ptr<TProtocolFactory> outputProtocolFactory)315 void setOutputProtocolFactory(std::shared_ptr<TProtocolFactory> outputProtocolFactory) 316 { 317 outputProtocolFactory_ = outputProtocolFactory; 318 } 319 setServerEventHandler(std::shared_ptr<TServerEventHandler> eventHandler)320 void setServerEventHandler(std::shared_ptr<TServerEventHandler> eventHandler) 321 { 322 eventHandler_ = eventHandler; 323 } 324 }; 325 326 /** 327 * Helper function to increase the max file descriptors limit 328 * for the current process and all of its children. 329 * By default, tries to increase it to as much as 2^24. 330 */ 331 #ifdef HAVE_SYS_RESOURCE_H 332 int increase_max_fds(int max_fds = (1 << 24)); 333 #endif 334 } // namespace server 335 } // namespace thrift 336 } // namespace apache 337 338 #endif // #ifndef _THRIFT_SERVER_TSERVER_H_ 339