/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #ifndef _THRIFT_SERVER_TTHREADEDSERVER_H_ #define _THRIFT_SERVER_TTHREADEDSERVER_H_ 1 #include #include #include #include #include namespace apache { namespace thrift { namespace server { /** * Manage clients using threads - threads are created one for each client and are * released when the client disconnects. This server is used to make a dynamically * scalable server up to the concurrent connection limit. */ class TThreadedServer : public TServerFramework { public: TThreadedServer( const std::shared_ptr& processorFactory, const std::shared_ptr& serverTransport, const std::shared_ptr& transportFactory, const std::shared_ptr& protocolFactory, const std::shared_ptr& threadFactory = std::shared_ptr( new apache::thrift::concurrency::ThreadFactory(false))); TThreadedServer( const std::shared_ptr& processor, const std::shared_ptr& serverTransport, const std::shared_ptr& transportFactory, const std::shared_ptr& protocolFactory, const std::shared_ptr& threadFactory = std::shared_ptr( new apache::thrift::concurrency::ThreadFactory(false))); TThreadedServer( const std::shared_ptr& processorFactory, const std::shared_ptr& serverTransport, const std::shared_ptr& inputTransportFactory, const std::shared_ptr& outputTransportFactory, const std::shared_ptr& inputProtocolFactory, const std::shared_ptr& outputProtocolFactory, const std::shared_ptr& threadFactory = std::shared_ptr( new apache::thrift::concurrency::ThreadFactory(false))); TThreadedServer( const std::shared_ptr& processor, const std::shared_ptr& serverTransport, const std::shared_ptr& inputTransportFactory, const std::shared_ptr& outputTransportFactory, const std::shared_ptr& inputProtocolFactory, const std::shared_ptr& outputProtocolFactory, const std::shared_ptr& threadFactory = std::shared_ptr( new apache::thrift::concurrency::ThreadFactory(false))); ~TThreadedServer() override; /** * Post-conditions (return guarantees): * There will be no clients connected. */ void serve() override; protected: /** * Drain recently connected clients by joining their threads - this is done lazily because * we cannot do it inside the thread context that is disconnecting. */ virtual void drainDeadClients(); /** * Implementation of TServerFramework::onClientConnected */ void onClientConnected(const std::shared_ptr& pClient) override /* override */; /** * Implementation of TServerFramework::onClientDisconnected */ void onClientDisconnected(TConnectedClient *pClient) override /* override */; std::shared_ptr threadFactory_; /** * A helper wrapper used to wrap the client in something we can use to maintain * the lifetime of the connected client within a detached thread. We cannot simply * track the threads because a shared_ptr hangs on to the Runnable it is * passed, and TServerFramework requires the runnable (TConnectedClient) to be * destroyed in order to work properly. */ class TConnectedClientRunner : public apache::thrift::concurrency::Runnable { public: TConnectedClientRunner(const std::shared_ptr& pClient); ~TConnectedClientRunner() override; void run() override /* override */; private: std::shared_ptr pClient_; }; apache::thrift::concurrency::Monitor clientMonitor_; typedef std::map > ClientMap; /** * A map of active clients */ ClientMap activeClientMap_; /** * A map of clients that have disconnected but their threads have not been joined */ ClientMap deadClientMap_; }; } } } // apache::thrift::server #endif // #ifndef _THRIFT_SERVER_TTHREADEDSERVER_H_