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_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 Service; 53 namespace testing { 54 class ServerBuilderPluginTest; 55 } // namespace testing 56 57 namespace internal { 58 class ExternalConnectionAcceptorImpl; 59 } // namespace internal 60 61 #ifndef GRPC_CALLBACK_API_NONEXPERIMENTAL 62 namespace experimental { 63 #endif 64 class CallbackGenericService; 65 #ifndef GRPC_CALLBACK_API_NONEXPERIMENTAL 66 } // namespace experimental 67 #endif 68 69 namespace experimental { 70 // EXPERIMENTAL API: 71 // Interface for a grpc server to build transports with connections created out 72 // of band. 73 // See ServerBuilder's AddExternalConnectionAcceptor API. 74 class ExternalConnectionAcceptor { 75 public: 76 struct NewConnectionParameters { 77 int listener_fd = -1; 78 int fd = -1; 79 ByteBuffer read_buffer; // data intended for the grpc server 80 }; ~ExternalConnectionAcceptor()81 virtual ~ExternalConnectionAcceptor() {} 82 // If called before grpc::Server is started or after it is shut down, the new 83 // connection will be closed. 84 virtual void HandleNewConnection(NewConnectionParameters* p) = 0; 85 }; 86 87 } // namespace experimental 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 selected_port[out] 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_impl::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_impl::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 #ifndef GRPC_CALLBACK_API_NONEXPERIMENTAL 273 /// Register a generic service that uses the callback API. 274 /// Matches requests with any :authority 275 /// This is mostly useful for writing generic gRPC Proxies where the exact 276 /// serialization format is unknown 277 ServerBuilder& RegisterCallbackGenericService( 278 grpc::experimental::CallbackGenericService* service); 279 #endif 280 281 enum class ExternalConnectionType { 282 FROM_FD = 0 // in the form of a file descriptor 283 }; 284 285 /// Register an acceptor to handle the externally accepted connection in 286 /// grpc server. The returned acceptor can be used to pass the connection 287 /// to grpc server, where a channel will be created with the provided 288 /// server credentials. 289 std::unique_ptr<grpc::experimental::ExternalConnectionAcceptor> 290 AddExternalConnectionAcceptor(ExternalConnectionType type, 291 std::shared_ptr<ServerCredentials> creds); 292 293 private: 294 ServerBuilder* builder_; 295 }; 296 297 #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL 298 /// Register a generic service that uses the callback API. 299 /// Matches requests with any :authority 300 /// This is mostly useful for writing generic gRPC Proxies where the exact 301 /// serialization format is unknown 302 ServerBuilder& RegisterCallbackGenericService( 303 grpc::CallbackGenericService* service); 304 #endif 305 306 /// NOTE: The function experimental() is not stable public API. It is a view 307 /// to the experimental components of this class. It may be changed or removed 308 /// at any time. experimental()309 experimental_type experimental() { return experimental_type(this); } 310 311 protected: 312 /// Experimental, to be deprecated 313 struct Port { 314 std::string addr; 315 std::shared_ptr<grpc_impl::ServerCredentials> creds; 316 int* selected_port; 317 }; 318 319 /// Experimental, to be deprecated 320 typedef std::unique_ptr<std::string> HostString; 321 struct NamedService { NamedServiceNamedService322 explicit NamedService(grpc::Service* s) : service(s) {} NamedServiceNamedService323 NamedService(const std::string& h, grpc::Service* s) 324 : host(new std::string(h)), service(s) {} 325 HostString host; 326 grpc::Service* service; 327 }; 328 329 /// Experimental, to be deprecated ports()330 std::vector<Port> ports() { return ports_; } 331 332 /// Experimental, to be deprecated services()333 std::vector<NamedService*> services() { 334 std::vector<NamedService*> service_refs; 335 for (auto& ptr : services_) { 336 service_refs.push_back(ptr.get()); 337 } 338 return service_refs; 339 } 340 341 /// Experimental, to be deprecated options()342 std::vector<grpc::ServerBuilderOption*> options() { 343 std::vector<grpc::ServerBuilderOption*> option_refs; 344 for (auto& ptr : options_) { 345 option_refs.push_back(ptr.get()); 346 } 347 return option_refs; 348 } 349 350 private: 351 friend class ::grpc::testing::ServerBuilderPluginTest; 352 353 struct SyncServerSettings { SyncServerSettingsSyncServerSettings354 SyncServerSettings() 355 : num_cqs(1), min_pollers(1), max_pollers(2), cq_timeout_msec(10000) {} 356 357 /// Number of server completion queues to create to listen to incoming RPCs. 358 int num_cqs; 359 360 /// Minimum number of threads per completion queue that should be listening 361 /// to incoming RPCs. 362 int min_pollers; 363 364 /// Maximum number of threads per completion queue that can be listening to 365 /// incoming RPCs. 366 int max_pollers; 367 368 /// The timeout for server completion queue's AsyncNext call. 369 int cq_timeout_msec; 370 }; 371 372 int max_receive_message_size_; 373 int max_send_message_size_; 374 std::vector<std::unique_ptr<grpc::ServerBuilderOption>> options_; 375 std::vector<std::unique_ptr<NamedService>> services_; 376 std::vector<Port> ports_; 377 378 SyncServerSettings sync_server_settings_; 379 380 /// List of completion queues added via \a AddCompletionQueue method. 381 std::vector<grpc_impl::ServerCompletionQueue*> cqs_; 382 383 std::shared_ptr<grpc_impl::ServerCredentials> creds_; 384 std::vector<std::unique_ptr<grpc::ServerBuilderPlugin>> plugins_; 385 grpc_resource_quota* resource_quota_; 386 grpc::AsyncGenericService* generic_service_{nullptr}; 387 #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL 388 grpc::CallbackGenericService* callback_generic_service_{nullptr}; 389 #else 390 grpc::experimental::CallbackGenericService* callback_generic_service_{ 391 nullptr}; 392 #endif 393 394 struct { 395 bool is_set; 396 grpc_compression_level level; 397 } maybe_default_compression_level_; 398 struct { 399 bool is_set; 400 grpc_compression_algorithm algorithm; 401 } maybe_default_compression_algorithm_; 402 uint32_t enabled_compression_algorithms_bitset_; 403 std::vector< 404 std::unique_ptr<grpc::experimental::ServerInterceptorFactoryInterface>> 405 interceptor_creators_; 406 std::vector<std::shared_ptr<grpc::internal::ExternalConnectionAcceptorImpl>> 407 acceptors_; 408 }; 409 410 } // namespace grpc 411 412 #endif // GRPCPP_SERVER_BUILDER_H 413