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