1 /* 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 */ 19 20 #ifndef _THRIFT_SERVER_TTHREADEDSERVER_H_ 21 #define _THRIFT_SERVER_TTHREADEDSERVER_H_ 1 22 23 #include <map> 24 #include <thrift/concurrency/Monitor.h> 25 #include <thrift/concurrency/ThreadFactory.h> 26 #include <thrift/concurrency/Thread.h> 27 #include <thrift/server/TServerFramework.h> 28 29 namespace apache { 30 namespace thrift { 31 namespace server { 32 33 /** 34 * Manage clients using threads - threads are created one for each client and are 35 * released when the client disconnects. This server is used to make a dynamically 36 * scalable server up to the concurrent connection limit. 37 */ 38 class TThreadedServer : public TServerFramework { 39 public: 40 TThreadedServer( 41 const std::shared_ptr<apache::thrift::TProcessorFactory>& processorFactory, 42 const std::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport, 43 const std::shared_ptr<apache::thrift::transport::TTransportFactory>& transportFactory, 44 const std::shared_ptr<apache::thrift::protocol::TProtocolFactory>& protocolFactory, 45 const std::shared_ptr<apache::thrift::concurrency::ThreadFactory>& threadFactory 46 = std::shared_ptr<apache::thrift::concurrency::ThreadFactory>( 47 new apache::thrift::concurrency::ThreadFactory(false))); 48 49 TThreadedServer( 50 const std::shared_ptr<apache::thrift::TProcessor>& processor, 51 const std::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport, 52 const std::shared_ptr<apache::thrift::transport::TTransportFactory>& transportFactory, 53 const std::shared_ptr<apache::thrift::protocol::TProtocolFactory>& protocolFactory, 54 const std::shared_ptr<apache::thrift::concurrency::ThreadFactory>& threadFactory 55 = std::shared_ptr<apache::thrift::concurrency::ThreadFactory>( 56 new apache::thrift::concurrency::ThreadFactory(false))); 57 58 TThreadedServer( 59 const std::shared_ptr<apache::thrift::TProcessorFactory>& processorFactory, 60 const std::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport, 61 const std::shared_ptr<apache::thrift::transport::TTransportFactory>& inputTransportFactory, 62 const std::shared_ptr<apache::thrift::transport::TTransportFactory>& outputTransportFactory, 63 const std::shared_ptr<apache::thrift::protocol::TProtocolFactory>& inputProtocolFactory, 64 const std::shared_ptr<apache::thrift::protocol::TProtocolFactory>& outputProtocolFactory, 65 const std::shared_ptr<apache::thrift::concurrency::ThreadFactory>& threadFactory 66 = std::shared_ptr<apache::thrift::concurrency::ThreadFactory>( 67 new apache::thrift::concurrency::ThreadFactory(false))); 68 69 TThreadedServer( 70 const std::shared_ptr<apache::thrift::TProcessor>& processor, 71 const std::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport, 72 const std::shared_ptr<apache::thrift::transport::TTransportFactory>& inputTransportFactory, 73 const std::shared_ptr<apache::thrift::transport::TTransportFactory>& outputTransportFactory, 74 const std::shared_ptr<apache::thrift::protocol::TProtocolFactory>& inputProtocolFactory, 75 const std::shared_ptr<apache::thrift::protocol::TProtocolFactory>& outputProtocolFactory, 76 const std::shared_ptr<apache::thrift::concurrency::ThreadFactory>& threadFactory 77 = std::shared_ptr<apache::thrift::concurrency::ThreadFactory>( 78 new apache::thrift::concurrency::ThreadFactory(false))); 79 80 ~TThreadedServer() override; 81 82 /** 83 * Post-conditions (return guarantees): 84 * There will be no clients connected. 85 */ 86 void serve() override; 87 88 protected: 89 /** 90 * Drain recently connected clients by joining their threads - this is done lazily because 91 * we cannot do it inside the thread context that is disconnecting. 92 */ 93 virtual void drainDeadClients(); 94 95 /** 96 * Implementation of TServerFramework::onClientConnected 97 */ 98 void onClientConnected(const std::shared_ptr<TConnectedClient>& pClient) override /* override */; 99 100 /** 101 * Implementation of TServerFramework::onClientDisconnected 102 */ 103 void onClientDisconnected(TConnectedClient *pClient) override /* override */; 104 105 std::shared_ptr<apache::thrift::concurrency::ThreadFactory> threadFactory_; 106 107 /** 108 * A helper wrapper used to wrap the client in something we can use to maintain 109 * the lifetime of the connected client within a detached thread. We cannot simply 110 * track the threads because a shared_ptr<Thread> hangs on to the Runnable it is 111 * passed, and TServerFramework requires the runnable (TConnectedClient) to be 112 * destroyed in order to work properly. 113 */ 114 class TConnectedClientRunner : public apache::thrift::concurrency::Runnable 115 { 116 public: 117 TConnectedClientRunner(const std::shared_ptr<TConnectedClient>& pClient); 118 ~TConnectedClientRunner() override; 119 void run() override /* override */; 120 private: 121 std::shared_ptr<TConnectedClient> pClient_; 122 }; 123 124 apache::thrift::concurrency::Monitor clientMonitor_; 125 126 typedef std::map<TConnectedClient *, std::shared_ptr<apache::thrift::concurrency::Thread> > ClientMap; 127 128 /** 129 * A map of active clients 130 */ 131 ClientMap activeClientMap_; 132 133 /** 134 * A map of clients that have disconnected but their threads have not been joined 135 */ 136 ClientMap deadClientMap_; 137 }; 138 139 } 140 } 141 } // apache::thrift::server 142 143 #endif // #ifndef _THRIFT_SERVER_TTHREADEDSERVER_H_ 144