1 /* 2 * 3 * Copyright 2015-2016 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 #ifndef GRPCPP_SERVER_BUILDER_IMPL_H 20 #define GRPCPP_SERVER_BUILDER_IMPL_H 21 22 #include <climits> 23 #include <map> 24 #include <memory> 25 #include <vector> 26 27 #include <grpc/impl/codegen/port_platform.h> 28 29 #include <grpc/compression.h> 30 #include <grpc/support/cpu.h> 31 #include <grpc/support/workaround_list.h> 32 #include <grpcpp/impl/channel_argument_option.h> 33 #include <grpcpp/impl/codegen/server_interceptor.h> 34 #include <grpcpp/impl/server_builder_option.h> 35 #include <grpcpp/impl/server_builder_plugin.h> 36 #include <grpcpp/server.h> 37 #include <grpcpp/support/config.h> 38 39 struct grpc_resource_quota; 40 41 namespace grpc_impl { 42 43 class CompletionQueue; 44 class Server; 45 class ServerCompletionQueue; 46 class ServerCredentials; 47 } // namespace grpc_impl 48 49 namespace grpc { 50 51 class AsyncGenericService; 52 class ResourceQuota; 53 class Service; 54 namespace testing { 55 class ServerBuilderPluginTest; 56 } // namespace testing 57 58 namespace internal { 59 class ExternalConnectionAcceptorImpl; 60 } // namespace internal 61 62 #ifndef GRPC_CALLBACK_API_NONEXPERIMENTAL 63 namespace experimental { 64 #endif 65 class CallbackGenericService; 66 #ifndef GRPC_CALLBACK_API_NONEXPERIMENTAL 67 } // namespace experimental 68 #endif 69 70 namespace experimental { 71 // EXPERIMENTAL API: 72 // Interface for a grpc server to build transports with connections created out 73 // of band. 74 // See ServerBuilder's AddExternalConnectionAcceptor API. 75 class ExternalConnectionAcceptor { 76 public: 77 struct NewConnectionParameters { 78 int listener_fd = -1; 79 int fd = -1; 80 ByteBuffer read_buffer; // data intended for the grpc server 81 }; ~ExternalConnectionAcceptor()82 virtual ~ExternalConnectionAcceptor() {} 83 // If called before grpc::Server is started or after it is shut down, the new 84 // connection will be closed. 85 virtual void HandleNewConnection(NewConnectionParameters* p) = 0; 86 }; 87 88 } // namespace experimental 89 } // namespace grpc 90 91 namespace grpc_impl { 92 93 /// A builder class for the creation and startup of \a grpc::Server instances. 94 class ServerBuilder { 95 public: 96 ServerBuilder(); 97 virtual ~ServerBuilder(); 98 99 ////////////////////////////////////////////////////////////////////////////// 100 // Primary API's 101 102 /// Return a running server which is ready for processing calls. 103 /// Before calling, one typically needs to ensure that: 104 /// 1. a service is registered - so that the server knows what to serve 105 /// (via RegisterService, or RegisterAsyncGenericService) 106 /// 2. a listening port has been added - so the server knows where to receive 107 /// traffic (via AddListeningPort) 108 /// 3. [for async api only] completion queues have been added via 109 /// AddCompletionQueue 110 /// 111 /// Will return a nullptr on errors. 112 virtual std::unique_ptr<grpc::Server> BuildAndStart(); 113 114 /// Register a service. This call does not take ownership of the service. 115 /// The service must exist for the lifetime of the \a Server instance returned 116 /// by \a BuildAndStart(). 117 /// Matches requests with any :authority 118 ServerBuilder& RegisterService(grpc::Service* service); 119 120 /// Enlists an endpoint \a addr (port with an optional IP address) to 121 /// bind the \a grpc::Server object to be created to. 122 /// 123 /// It can be invoked multiple times. 124 /// 125 /// \param addr_uri The address to try to bind to the server in URI form. If 126 /// the scheme name is omitted, "dns:///" is assumed. To bind to any address, 127 /// please use IPv6 any, i.e., [::]:<port>, which also accepts IPv4 128 /// connections. Valid values include dns:///localhost:1234, / 129 /// 192.168.1.1:31416, dns:///[::1]:27182, etc.). 130 /// \param creds The credentials associated with the server. 131 /// \param selected_port[out] If not `nullptr`, gets populated with the port 132 /// number bound to the \a grpc::Server for the corresponding endpoint after 133 /// it is successfully bound by BuildAndStart(), 0 otherwise. AddListeningPort 134 /// does not modify this pointer. 135 ServerBuilder& AddListeningPort( 136 const std::string& addr_uri, 137 std::shared_ptr<grpc_impl::ServerCredentials> creds, 138 int* selected_port = nullptr); 139 140 /// Add a completion queue for handling asynchronous services. 141 /// 142 /// Best performance is typically obtained by using one thread per polling 143 /// completion queue. 144 /// 145 /// Caller is required to shutdown the server prior to shutting down the 146 /// returned completion queue. Caller is also required to drain the 147 /// completion queue after shutting it down. A typical usage scenario: 148 /// 149 /// // While building the server: 150 /// ServerBuilder builder; 151 /// ... 152 /// cq_ = builder.AddCompletionQueue(); 153 /// server_ = builder.BuildAndStart(); 154 /// 155 /// // While shutting down the server; 156 /// server_->Shutdown(); 157 /// cq_->Shutdown(); // Always *after* the associated server's Shutdown()! 158 /// // Drain the cq_ that was created 159 /// void* ignored_tag; 160 /// bool ignored_ok; 161 /// while (cq_->Next(&ignored_tag, &ignored_ok)) { } 162 /// 163 /// \param is_frequently_polled This is an optional parameter to inform gRPC 164 /// library about whether this completion queue would be frequently polled 165 /// (i.e. by calling \a Next() or \a AsyncNext()). The default value is 166 /// 'true' and is the recommended setting. Setting this to 'false' (i.e. 167 /// not polling the completion queue frequently) will have a significantly 168 /// negative performance impact and hence should not be used in production 169 /// use cases. 170 std::unique_ptr<grpc_impl::ServerCompletionQueue> AddCompletionQueue( 171 bool is_frequently_polled = true); 172 173 ////////////////////////////////////////////////////////////////////////////// 174 // Less commonly used RegisterService variants 175 176 /// Register a service. This call does not take ownership of the service. 177 /// The service must exist for the lifetime of the \a Server instance 178 /// returned by \a BuildAndStart(). Only matches requests with :authority \a 179 /// host 180 ServerBuilder& RegisterService(const std::string& host, 181 grpc::Service* service); 182 183 /// Register a generic service. 184 /// Matches requests with any :authority 185 /// This is mostly useful for writing generic gRPC Proxies where the exact 186 /// serialization format is unknown 187 ServerBuilder& RegisterAsyncGenericService( 188 grpc::AsyncGenericService* service); 189 190 ////////////////////////////////////////////////////////////////////////////// 191 // Fine control knobs 192 193 /// Set max receive message size in bytes. 194 /// The default is GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH. SetMaxReceiveMessageSize(int max_receive_message_size)195 ServerBuilder& SetMaxReceiveMessageSize(int max_receive_message_size) { 196 max_receive_message_size_ = max_receive_message_size; 197 return *this; 198 } 199 200 /// Set max send message size in bytes. 201 /// The default is GRPC_DEFAULT_MAX_SEND_MESSAGE_LENGTH. SetMaxSendMessageSize(int max_send_message_size)202 ServerBuilder& SetMaxSendMessageSize(int max_send_message_size) { 203 max_send_message_size_ = max_send_message_size; 204 return *this; 205 } 206 207 /// \deprecated For backward compatibility. SetMaxMessageSize(int max_message_size)208 ServerBuilder& SetMaxMessageSize(int max_message_size) { 209 return SetMaxReceiveMessageSize(max_message_size); 210 } 211 212 /// Set the support status for compression algorithms. All algorithms are 213 /// enabled by default. 214 /// 215 /// Incoming calls compressed with an unsupported algorithm will fail with 216 /// \a GRPC_STATUS_UNIMPLEMENTED. 217 ServerBuilder& SetCompressionAlgorithmSupportStatus( 218 grpc_compression_algorithm algorithm, bool enabled); 219 220 /// The default compression level to use for all channel calls in the 221 /// absence of a call-specific level. 222 ServerBuilder& SetDefaultCompressionLevel(grpc_compression_level level); 223 224 /// The default compression algorithm to use for all channel calls in the 225 /// absence of a call-specific level. Note that it overrides any compression 226 /// level set by \a SetDefaultCompressionLevel. 227 ServerBuilder& SetDefaultCompressionAlgorithm( 228 grpc_compression_algorithm algorithm); 229 230 /// Set the attached buffer pool for this server 231 ServerBuilder& SetResourceQuota(const grpc::ResourceQuota& resource_quota); 232 233 ServerBuilder& SetOption(std::unique_ptr<grpc::ServerBuilderOption> option); 234 235 /// Options for synchronous servers. 236 enum SyncServerOption { 237 NUM_CQS, ///< Number of completion queues. 238 MIN_POLLERS, ///< Minimum number of polling threads. 239 MAX_POLLERS, ///< Maximum number of polling threads. 240 CQ_TIMEOUT_MSEC ///< Completion queue timeout in milliseconds. 241 }; 242 243 /// Only useful if this is a Synchronous server. 244 ServerBuilder& SetSyncServerOption(SyncServerOption option, int value); 245 246 /// Add a channel argument (an escape hatch to tuning core library parameters 247 /// directly) 248 template <class T> AddChannelArgument(const std::string & arg,const T & value)249 ServerBuilder& AddChannelArgument(const std::string& arg, const T& value) { 250 return SetOption(grpc::MakeChannelArgumentOption(arg, value)); 251 } 252 253 /// For internal use only: Register a ServerBuilderPlugin factory function. 254 static void InternalAddPluginFactory( 255 std::unique_ptr<grpc::ServerBuilderPlugin> (*CreatePlugin)()); 256 257 /// Enable a server workaround. Do not use unless you know what the workaround 258 /// does. For explanation and detailed descriptions of workarounds, see 259 /// doc/workarounds.md. 260 ServerBuilder& EnableWorkaround(grpc_workaround_list id); 261 262 /// NOTE: class experimental_type is not part of the public API of this class. 263 /// TODO(yashykt): Integrate into public API when this is no longer 264 /// experimental. 265 class experimental_type { 266 public: experimental_type(grpc_impl::ServerBuilder * builder)267 explicit experimental_type(grpc_impl::ServerBuilder* builder) 268 : builder_(builder) {} 269 SetInterceptorCreators(std::vector<std::unique_ptr<grpc::experimental::ServerInterceptorFactoryInterface>> interceptor_creators)270 void SetInterceptorCreators( 271 std::vector<std::unique_ptr< 272 grpc::experimental::ServerInterceptorFactoryInterface>> 273 interceptor_creators) { 274 builder_->interceptor_creators_ = std::move(interceptor_creators); 275 } 276 277 #ifndef GRPC_CALLBACK_API_NONEXPERIMENTAL 278 /// Register a generic service that uses the callback API. 279 /// Matches requests with any :authority 280 /// This is mostly useful for writing generic gRPC Proxies where the exact 281 /// serialization format is unknown 282 ServerBuilder& RegisterCallbackGenericService( 283 grpc::experimental::CallbackGenericService* service); 284 #endif 285 286 enum class ExternalConnectionType { 287 FROM_FD = 0 // in the form of a file descriptor 288 }; 289 290 /// Register an acceptor to handle the externally accepted connection in 291 /// grpc server. The returned acceptor can be used to pass the connection 292 /// to grpc server, where a channel will be created with the provided 293 /// server credentials. 294 std::unique_ptr<grpc::experimental::ExternalConnectionAcceptor> 295 AddExternalConnectionAcceptor(ExternalConnectionType type, 296 std::shared_ptr<ServerCredentials> creds); 297 298 private: 299 ServerBuilder* builder_; 300 }; 301 302 #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL 303 /// Register a generic service that uses the callback API. 304 /// Matches requests with any :authority 305 /// This is mostly useful for writing generic gRPC Proxies where the exact 306 /// serialization format is unknown 307 ServerBuilder& RegisterCallbackGenericService( 308 grpc::CallbackGenericService* service); 309 #endif 310 311 /// NOTE: The function experimental() is not stable public API. It is a view 312 /// to the experimental components of this class. It may be changed or removed 313 /// at any time. experimental()314 experimental_type experimental() { return experimental_type(this); } 315 316 protected: 317 /// Experimental, to be deprecated 318 struct Port { 319 std::string addr; 320 std::shared_ptr<grpc_impl::ServerCredentials> creds; 321 int* selected_port; 322 }; 323 324 /// Experimental, to be deprecated 325 typedef std::unique_ptr<std::string> HostString; 326 struct NamedService { NamedServiceNamedService327 explicit NamedService(grpc::Service* s) : service(s) {} NamedServiceNamedService328 NamedService(const std::string& h, grpc::Service* s) 329 : host(new std::string(h)), service(s) {} 330 HostString host; 331 grpc::Service* service; 332 }; 333 334 /// Experimental, to be deprecated ports()335 std::vector<Port> ports() { return ports_; } 336 337 /// Experimental, to be deprecated services()338 std::vector<NamedService*> services() { 339 std::vector<NamedService*> service_refs; 340 for (auto& ptr : services_) { 341 service_refs.push_back(ptr.get()); 342 } 343 return service_refs; 344 } 345 346 /// Experimental, to be deprecated options()347 std::vector<grpc::ServerBuilderOption*> options() { 348 std::vector<grpc::ServerBuilderOption*> option_refs; 349 for (auto& ptr : options_) { 350 option_refs.push_back(ptr.get()); 351 } 352 return option_refs; 353 } 354 355 private: 356 friend class ::grpc::testing::ServerBuilderPluginTest; 357 358 struct SyncServerSettings { SyncServerSettingsSyncServerSettings359 SyncServerSettings() 360 : num_cqs(1), min_pollers(1), max_pollers(2), cq_timeout_msec(10000) {} 361 362 /// Number of server completion queues to create to listen to incoming RPCs. 363 int num_cqs; 364 365 /// Minimum number of threads per completion queue that should be listening 366 /// to incoming RPCs. 367 int min_pollers; 368 369 /// Maximum number of threads per completion queue that can be listening to 370 /// incoming RPCs. 371 int max_pollers; 372 373 /// The timeout for server completion queue's AsyncNext call. 374 int cq_timeout_msec; 375 }; 376 377 int max_receive_message_size_; 378 int max_send_message_size_; 379 std::vector<std::unique_ptr<grpc::ServerBuilderOption>> options_; 380 std::vector<std::unique_ptr<NamedService>> services_; 381 std::vector<Port> ports_; 382 383 SyncServerSettings sync_server_settings_; 384 385 /// List of completion queues added via \a AddCompletionQueue method. 386 std::vector<grpc_impl::ServerCompletionQueue*> cqs_; 387 388 std::shared_ptr<grpc_impl::ServerCredentials> creds_; 389 std::vector<std::unique_ptr<grpc::ServerBuilderPlugin>> plugins_; 390 grpc_resource_quota* resource_quota_; 391 grpc::AsyncGenericService* generic_service_{nullptr}; 392 #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL 393 grpc::CallbackGenericService* callback_generic_service_{nullptr}; 394 #else 395 grpc::experimental::CallbackGenericService* callback_generic_service_{ 396 nullptr}; 397 #endif 398 399 struct { 400 bool is_set; 401 grpc_compression_level level; 402 } maybe_default_compression_level_; 403 struct { 404 bool is_set; 405 grpc_compression_algorithm algorithm; 406 } maybe_default_compression_algorithm_; 407 uint32_t enabled_compression_algorithms_bitset_; 408 std::vector< 409 std::unique_ptr<grpc::experimental::ServerInterceptorFactoryInterface>> 410 interceptor_creators_; 411 std::vector<std::shared_ptr<grpc::internal::ExternalConnectionAcceptorImpl>> 412 acceptors_; 413 }; 414 415 } // namespace grpc_impl 416 417 #endif // GRPCPP_SERVER_BUILDER_IMPL_H 418