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