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_TSERVERFRAMEWORK_H_ 26 #define _THRIFT_SERVER_TSERVERFRAMEWORK_H_ 1 27 28 #include <memory> 29 #include <stdint.h> 30 #include <thrift/TProcessor.h> 31 #include <thrift/server/TConnectedClient.h> 32 #include <thrift/server/TServer.h> 33 #include <thrift/transport/TServerTransport.h> 34 #include <thrift/transport/TTransport.h> 35 36 namespace apache 37 { 38 namespace thrift 39 { 40 namespace server 41 { 42 43 /** 44 * TServerFramework provides a single consolidated processing loop for 45 * servers. By having a single processing loop, behavior between servers 46 * is more predictable and maintenance cost is lowered. Implementations 47 * of TServerFramework must provide a method to deal with a client that 48 * connects and one that disconnects. 49 * 50 * While this functionality could be rolled directly into TServer, and 51 * probably should be, it would break the TServer interface contract so 52 * to maintain backwards compatibility for third party servers, no TServers 53 * were harmed in the making of this class. 54 */ 55 class TServerFramework : public TServer 56 { 57 public: 58 TServerFramework( 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> 62 &transportFactory, 63 const std::shared_ptr<apache::thrift::protocol::TProtocolFactory> &protocolFactory); 64 65 TServerFramework( 66 const std::shared_ptr<apache::thrift::TProcessor> &processor, 67 const std::shared_ptr<apache::thrift::transport::TServerTransport> &serverTransport, 68 const std::shared_ptr<apache::thrift::transport::TTransportFactory> 69 &transportFactory, 70 const std::shared_ptr<apache::thrift::protocol::TProtocolFactory> &protocolFactory); 71 72 TServerFramework( 73 const std::shared_ptr<apache::thrift::TProcessorFactory> &processorFactory, 74 const std::shared_ptr<apache::thrift::transport::TServerTransport> &serverTransport, 75 const std::shared_ptr<apache::thrift::transport::TTransportFactory> 76 &inputTransportFactory, 77 const std::shared_ptr<apache::thrift::transport::TTransportFactory> 78 &outputTransportFactory, 79 const std::shared_ptr<apache::thrift::protocol::TProtocolFactory> 80 &inputProtocolFactory, 81 const std::shared_ptr<apache::thrift::protocol::TProtocolFactory> 82 &outputProtocolFactory); 83 84 TServerFramework( 85 const std::shared_ptr<apache::thrift::TProcessor> &processor, 86 const std::shared_ptr<apache::thrift::transport::TServerTransport> &serverTransport, 87 const std::shared_ptr<apache::thrift::transport::TTransportFactory> 88 &inputTransportFactory, 89 const std::shared_ptr<apache::thrift::transport::TTransportFactory> 90 &outputTransportFactory, 91 const std::shared_ptr<apache::thrift::protocol::TProtocolFactory> 92 &inputProtocolFactory, 93 const std::shared_ptr<apache::thrift::protocol::TProtocolFactory> 94 &outputProtocolFactory); 95 96 ~TServerFramework(); 97 98 /** 99 * Accept clients from the TServerTransport and add them for processing. 100 * Call stop() on another thread to interrupt processing 101 * and return control to the caller. 102 * Post-conditions (return guarantees): 103 * The serverTransport will be closed. 104 */ 105 virtual void serve() override; 106 107 /** 108 * Interrupt serve() so that it meets post-conditions and returns. 109 */ 110 virtual void stop() override; 111 112 /** 113 * Get the concurrent client limit. 114 * \returns the concurrent client limit 115 */ 116 virtual int64_t getConcurrentClientLimit() const; 117 118 /** 119 * Get the number of currently connected clients. 120 * \returns the number of currently connected clients 121 */ 122 virtual int64_t getConcurrentClientCount() const; 123 124 /** 125 * Get the highest number of concurrent clients. 126 * \returns the highest number of concurrent clients 127 */ 128 virtual int64_t getConcurrentClientCountHWM() const; 129 130 /** 131 * Set the concurrent client limit. This can be changed while 132 * the server is serving however it will not necessarily be 133 * enforced until the next client is accepted and added. If the 134 * limit is lowered below the number of connected clients, no 135 * action is taken to disconnect the clients. 136 * The default value used if this is not called is INT64_MAX. 137 * \param[in] newLimit the new limit of concurrent clients 138 * \throws std::invalid_argument if newLimit is less than 1 139 */ 140 virtual void setConcurrentClientLimit(int64_t newLimit); 141 142 protected: 143 /** 144 * A client has connected. The implementation is responsible for managing the 145 * lifetime of the client object. This is called during the serve() thread, 146 * therefore a failure to return quickly will result in new client connection 147 * delays. 148 * 149 * \param[in] pClient the newly connected client 150 */ 151 virtual void onClientConnected(const std::shared_ptr<TConnectedClient> &pClient) = 0; 152 153 /** 154 * A client has disconnected. 155 * When called: 156 * The server no longer tracks the client. 157 * The client TTransport has already been closed. 158 * The implementation must not delete the pointer. 159 * 160 * \param[in] pClient the disconnected client 161 */ 162 virtual void onClientDisconnected(TConnectedClient *pClient) = 0; 163 164 private: 165 /** 166 * Common handling for new connected clients. Implements concurrent 167 * client rate limiting after onClientConnected returns by blocking the 168 * serve() thread if the limit has been reached. 169 */ 170 void newlyConnectedClient(const std::shared_ptr<TConnectedClient> &pClient); 171 172 /** 173 * Smart pointer client deletion. 174 * Calls onClientDisconnected and then deletes pClient. 175 */ 176 void disposeConnectedClient(TConnectedClient *pClient); 177 178 /** 179 * The number of concurrent clients. 180 */ 181 int64_t clients_; 182 183 /** 184 * The high water mark of concurrent clients. 185 */ 186 int64_t hwm_; 187 188 /** 189 * The limit on the number of concurrent clients. 190 */ 191 int64_t limit_; 192 }; 193 } // namespace server 194 } // namespace thrift 195 } // namespace apache 196 197 #endif // #ifndef _THRIFT_SERVER_TSERVERFRAMEWORK_H_ 198