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_H 20 #define GRPCPP_SERVER_BUILDER_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 { 42 43 class CompletionQueue; 44 class Server; 45 class ServerCompletionQueue; 46 class AsyncGenericService; 47 class ResourceQuota; 48 class ServerCredentials; 49 class Service; 50 namespace testing { 51 class ServerBuilderPluginTest; 52 } // namespace testing 53 54 namespace internal { 55 class ExternalConnectionAcceptorImpl; 56 } // namespace internal 57 58 #ifndef GRPC_CALLBACK_API_NONEXPERIMENTAL 59 namespace experimental { 60 #endif 61 class CallbackGenericService; 62 #ifndef GRPC_CALLBACK_API_NONEXPERIMENTAL 63 } // namespace experimental 64 #endif 65 66 namespace experimental { 67 // EXPERIMENTAL API: 68 // Interface for a grpc server to build transports with connections created out 69 // of band. 70 // See ServerBuilder's AddExternalConnectionAcceptor API. 71 class ExternalConnectionAcceptor { 72 public: 73 struct NewConnectionParameters { 74 int listener_fd = -1; 75 int fd = -1; 76 ByteBuffer read_buffer; // data intended for the grpc server 77 }; ~ExternalConnectionAcceptor()78 virtual ~ExternalConnectionAcceptor() {} 79 // If called before grpc::Server is started or after it is shut down, the new 80 // connection will be closed. 81 virtual void HandleNewConnection(NewConnectionParameters* p) = 0; 82 }; 83 84 } // namespace experimental 85 } // namespace grpc 86 87 namespace grpc { 88 89 /// A builder class for the creation and startup of \a grpc::Server instances. 90 class ServerBuilder { 91 public: 92 ServerBuilder(); 93 virtual ~ServerBuilder(); 94 95 ////////////////////////////////////////////////////////////////////////////// 96 // Primary API's 97 98 /// Return a running server which is ready for processing calls. 99 /// Before calling, one typically needs to ensure that: 100 /// 1. a service is registered - so that the server knows what to serve 101 /// (via RegisterService, or RegisterAsyncGenericService) 102 /// 2. a listening port has been added - so the server knows where to receive 103 /// traffic (via AddListeningPort) 104 /// 3. [for async api only] completion queues have been added via 105 /// AddCompletionQueue 106 /// 107 /// Will return a nullptr on errors. 108 virtual std::unique_ptr<grpc::Server> BuildAndStart(); 109 110 /// Register a service. This call does not take ownership of the service. 111 /// The service must exist for the lifetime of the \a Server instance returned 112 /// by \a BuildAndStart(). 113 /// Matches requests with any :authority 114 ServerBuilder& RegisterService(grpc::Service* service); 115 116 /// Enlists an endpoint \a addr (port with an optional IP address) to 117 /// bind the \a grpc::Server object to be created to. 118 /// 119 /// It can be invoked multiple times. 120 /// 121 /// \param addr_uri The address to try to bind to the server in URI form. If 122 /// the scheme name is omitted, "dns:///" is assumed. To bind to any address, 123 /// please use IPv6 any, i.e., [::]:<port>, which also accepts IPv4 124 /// connections. Valid values include dns:///localhost:1234, / 125 /// 192.168.1.1:31416, dns:///[::1]:27182, etc.). 126 /// \param creds The credentials associated with the server. 127 /// \param[out] selected_port If not `nullptr`, gets populated with the port 128 /// number bound to the \a grpc::Server for the corresponding endpoint after 129 /// it is successfully bound by BuildAndStart(), 0 otherwise. AddListeningPort 130 /// does not modify this pointer. 131 ServerBuilder& AddListeningPort( 132 const std::string& addr_uri, 133 std::shared_ptr<grpc::ServerCredentials> creds, 134 int* selected_port = nullptr); 135 136 /// Add a completion queue for handling asynchronous services. 137 /// 138 /// Best performance is typically obtained by using one thread per polling 139 /// completion queue. 140 /// 141 /// Caller is required to shutdown the server prior to shutting down the 142 /// returned completion queue. Caller is also required to drain the 143 /// completion queue after shutting it down. A typical usage scenario: 144 /// 145 /// // While building the server: 146 /// ServerBuilder builder; 147 /// ... 148 /// cq_ = builder.AddCompletionQueue(); 149 /// server_ = builder.BuildAndStart(); 150 /// 151 /// // While shutting down the server; 152 /// server_->Shutdown(); 153 /// cq_->Shutdown(); // Always *after* the associated server's Shutdown()! 154 /// // Drain the cq_ that was created 155 /// void* ignored_tag; 156 /// bool ignored_ok; 157 /// while (cq_->Next(&ignored_tag, &ignored_ok)) { } 158 /// 159 /// \param is_frequently_polled This is an optional parameter to inform gRPC 160 /// library about whether this completion queue would be frequently polled 161 /// (i.e. by calling \a Next() or \a AsyncNext()). The default value is 162 /// 'true' and is the recommended setting. Setting this to 'false' (i.e. 163 /// not polling the completion queue frequently) will have a significantly 164 /// negative performance impact and hence should not be used in production 165 /// use cases. 166 std::unique_ptr<grpc::ServerCompletionQueue> AddCompletionQueue( 167 bool is_frequently_polled = true); 168 169 ////////////////////////////////////////////////////////////////////////////// 170 // Less commonly used RegisterService variants 171 172 /// Register a service. This call does not take ownership of the service. 173 /// The service must exist for the lifetime of the \a Server instance 174 /// returned by \a BuildAndStart(). Only matches requests with :authority \a 175 /// host 176 ServerBuilder& RegisterService(const std::string& host, 177 grpc::Service* service); 178 179 /// Register a generic service. 180 /// Matches requests with any :authority 181 /// This is mostly useful for writing generic gRPC Proxies where the exact 182 /// serialization format is unknown 183 ServerBuilder& RegisterAsyncGenericService( 184 grpc::AsyncGenericService* service); 185 186 ////////////////////////////////////////////////////////////////////////////// 187 // Fine control knobs 188 189 /// Set max receive message size in bytes. 190 /// The default is GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH. SetMaxReceiveMessageSize(int max_receive_message_size)191 ServerBuilder& SetMaxReceiveMessageSize(int max_receive_message_size) { 192 max_receive_message_size_ = max_receive_message_size; 193 return *this; 194 } 195 196 /// Set max send message size in bytes. 197 /// The default is GRPC_DEFAULT_MAX_SEND_MESSAGE_LENGTH. SetMaxSendMessageSize(int max_send_message_size)198 ServerBuilder& SetMaxSendMessageSize(int max_send_message_size) { 199 max_send_message_size_ = max_send_message_size; 200 return *this; 201 } 202 203 /// \deprecated For backward compatibility. SetMaxMessageSize(int max_message_size)204 ServerBuilder& SetMaxMessageSize(int max_message_size) { 205 return SetMaxReceiveMessageSize(max_message_size); 206 } 207 208 /// Set the support status for compression algorithms. All algorithms are 209 /// enabled by default. 210 /// 211 /// Incoming calls compressed with an unsupported algorithm will fail with 212 /// \a GRPC_STATUS_UNIMPLEMENTED. 213 ServerBuilder& SetCompressionAlgorithmSupportStatus( 214 grpc_compression_algorithm algorithm, bool enabled); 215 216 /// The default compression level to use for all channel calls in the 217 /// absence of a call-specific level. 218 ServerBuilder& SetDefaultCompressionLevel(grpc_compression_level level); 219 220 /// The default compression algorithm to use for all channel calls in the 221 /// absence of a call-specific level. Note that it overrides any compression 222 /// level set by \a SetDefaultCompressionLevel. 223 ServerBuilder& SetDefaultCompressionAlgorithm( 224 grpc_compression_algorithm algorithm); 225 226 /// Set the attached buffer pool for this server 227 ServerBuilder& SetResourceQuota(const grpc::ResourceQuota& resource_quota); 228 229 ServerBuilder& SetOption(std::unique_ptr<grpc::ServerBuilderOption> option); 230 231 /// Options for synchronous servers. 232 enum SyncServerOption { 233 NUM_CQS, ///< Number of completion queues. 234 MIN_POLLERS, ///< Minimum number of polling threads. 235 MAX_POLLERS, ///< Maximum number of polling threads. 236 CQ_TIMEOUT_MSEC ///< Completion queue timeout in milliseconds. 237 }; 238 239 /// Only useful if this is a Synchronous server. 240 ServerBuilder& SetSyncServerOption(SyncServerOption option, int value); 241 242 /// Add a channel argument (an escape hatch to tuning core library parameters 243 /// directly) 244 template <class T> AddChannelArgument(const std::string & arg,const T & value)245 ServerBuilder& AddChannelArgument(const std::string& arg, const T& value) { 246 return SetOption(grpc::MakeChannelArgumentOption(arg, value)); 247 } 248 249 /// For internal use only: Register a ServerBuilderPlugin factory function. 250 static void InternalAddPluginFactory( 251 std::unique_ptr<grpc::ServerBuilderPlugin> (*CreatePlugin)()); 252 253 /// Enable a server workaround. Do not use unless you know what the workaround 254 /// does. For explanation and detailed descriptions of workarounds, see 255 /// doc/workarounds.md. 256 ServerBuilder& EnableWorkaround(grpc_workaround_list id); 257 258 /// NOTE: class experimental_type is not part of the public API of this class. 259 /// TODO(yashykt): Integrate into public API when this is no longer 260 /// experimental. 261 class experimental_type { 262 public: experimental_type(ServerBuilder * builder)263 explicit experimental_type(ServerBuilder* builder) : builder_(builder) {} 264 SetInterceptorCreators(std::vector<std::unique_ptr<grpc::experimental::ServerInterceptorFactoryInterface>> interceptor_creators)265 void SetInterceptorCreators( 266 std::vector<std::unique_ptr< 267 grpc::experimental::ServerInterceptorFactoryInterface>> 268 interceptor_creators) { 269 builder_->interceptor_creators_ = std::move(interceptor_creators); 270 } 271 272 /// Set the allocator for creating and releasing callback server context. 273 /// Takes the owndership of the allocator. 274 ServerBuilder& SetContextAllocator( 275 std::unique_ptr<grpc::ContextAllocator> context_allocator); 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<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 /// Experimental API, subject to change. set_fetcher(grpc_server_config_fetcher * server_config_fetcher)356 void set_fetcher(grpc_server_config_fetcher* server_config_fetcher) { 357 server_config_fetcher_ = server_config_fetcher; 358 } 359 360 private: 361 friend class ::grpc::testing::ServerBuilderPluginTest; 362 363 struct SyncServerSettings { SyncServerSettingsSyncServerSettings364 SyncServerSettings() 365 : num_cqs(1), min_pollers(1), max_pollers(2), cq_timeout_msec(10000) {} 366 367 /// Number of server completion queues to create to listen to incoming RPCs. 368 int num_cqs; 369 370 /// Minimum number of threads per completion queue that should be listening 371 /// to incoming RPCs. 372 int min_pollers; 373 374 /// Maximum number of threads per completion queue that can be listening to 375 /// incoming RPCs. 376 int max_pollers; 377 378 /// The timeout for server completion queue's AsyncNext call. 379 int cq_timeout_msec; 380 }; 381 382 int max_receive_message_size_; 383 int max_send_message_size_; 384 std::vector<std::unique_ptr<grpc::ServerBuilderOption>> options_; 385 std::vector<std::unique_ptr<NamedService>> services_; 386 std::vector<Port> ports_; 387 388 SyncServerSettings sync_server_settings_; 389 390 /// List of completion queues added via \a AddCompletionQueue method. 391 std::vector<grpc::ServerCompletionQueue*> cqs_; 392 393 std::shared_ptr<grpc::ServerCredentials> creds_; 394 std::vector<std::unique_ptr<grpc::ServerBuilderPlugin>> plugins_; 395 grpc_resource_quota* resource_quota_; 396 grpc::AsyncGenericService* generic_service_{nullptr}; 397 std::unique_ptr<ContextAllocator> context_allocator_; 398 #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL 399 grpc::CallbackGenericService* callback_generic_service_{nullptr}; 400 #else 401 grpc::experimental::CallbackGenericService* callback_generic_service_{ 402 nullptr}; 403 #endif 404 405 struct { 406 bool is_set; 407 grpc_compression_level level; 408 } maybe_default_compression_level_; 409 struct { 410 bool is_set; 411 grpc_compression_algorithm algorithm; 412 } maybe_default_compression_algorithm_; 413 uint32_t enabled_compression_algorithms_bitset_; 414 std::vector< 415 std::unique_ptr<grpc::experimental::ServerInterceptorFactoryInterface>> 416 interceptor_creators_; 417 std::vector<std::shared_ptr<grpc::internal::ExternalConnectionAcceptorImpl>> 418 acceptors_; 419 grpc_server_config_fetcher* server_config_fetcher_ = nullptr; 420 }; 421 422 } // namespace grpc 423 424 #endif // GRPCPP_SERVER_BUILDER_H 425