14 """Server-side implementation of gRPC Asyncio Python."""
16 from concurrent.futures
import Executor
17 from typing
import Any, Optional, Sequence
20 from grpc
import _common
21 from grpc
import _compression
24 from .
import _base_server
25 from ._interceptor
import ServerInterceptor
26 from ._typing
import ChannelArgumentType
31 compression_option = _compression.create_channel_option(compression)
32 return tuple(base_options) + compression_option
38 def __init__(self, thread_pool: Optional[Executor],
40 interceptors: Optional[Sequence[Any]],
41 options: ChannelArgumentType,
42 maximum_concurrent_rpcs: Optional[int],
44 self.
_loop = cygrpc.get_working_loop()
46 invalid_interceptors = [
47 interceptor
for interceptor
in interceptors
48 if not isinstance(interceptor, ServerInterceptor)
50 if invalid_interceptors:
52 'Interceptor must be ServerInterceptor, the '
53 f
'following are invalid: {invalid_interceptors}')
54 self.
_server = cygrpc.AioServer(
55 self.
_loop, thread_pool, generic_handlers, interceptors,
57 maximum_concurrent_rpcs)
62 """Registers GenericRpcHandlers with this Server.
64 This method is only safe to call before the server is started.
67 generic_rpc_handlers: A sequence of GenericRpcHandlers that will be
73 """Opens an insecure port for accepting RPCs.
75 This method may only be called before starting the server.
78 address: The address for which to open a port. If the port is 0,
79 or not specified in the address, then the gRPC runtime will choose a port.
82 An integer port on which the server will accept RPC requests.
84 return _common.validate_port_binding_result(
89 """Opens a secure port for accepting RPCs.
91 This method may only be called before starting the server.
94 address: The address for which to open a port.
95 if the port is 0, or not specified in the address, then the gRPC
96 runtime will choose a port.
97 server_credentials: A ServerCredentials object.
100 An integer port on which the server will accept RPC requests.
102 return _common.validate_port_binding_result(
108 """Starts this Server.
110 This method may only be called once. (i.e. it is not idempotent).
114 async
def stop(self, grace: Optional[float]) ->
None:
115 """Stops this Server.
117 This method immediately stops the server from servicing new RPCs in
120 If a grace period is specified, this method returns immediately and all
121 RPCs active at the end of the grace period are aborted. If a grace
122 period is not specified (by passing None for grace), all existing RPCs
123 are aborted immediately and this method blocks until the last RPC
126 This method is idempotent and may be called at any time. Passing a
127 smaller grace value in a subsequent call will have the effect of
128 stopping the Server sooner (passing None will have the effect of
129 stopping the server immediately). Passing a larger grace value in a
130 subsequent call will not have the effect of stopping the server later
131 (i.e. the most restrictive grace value is used).
134 grace: A duration of time in seconds or None.
136 await self.
_server.shutdown(grace)
139 timeout: Optional[float] =
None) -> bool:
140 """Block current coroutine until the server stops.
142 This is an EXPERIMENTAL API.
144 The wait will not consume computational resources during blocking, and
145 it will block until one of the two following conditions are met:
147 1) The server is stopped or terminated;
148 2) A timeout occurs if timeout is not `None`.
150 The timeout argument works in the same way as `threading.Event.wait()`.
151 https://docs.python.org/3/library/threading.html#threading.Event.wait
154 timeout: A floating point number specifying a timeout for the
155 operation in seconds.
158 A bool indicates if the operation times out.
163 """Schedules a graceful shutdown in current event loop.
165 The Cython AioServer doesn't hold a ref-count to this class. It should
166 be safe to slightly extend the underlying Cython object's life span.
168 if hasattr(self,
'_server'):
170 cygrpc.schedule_coro_threadsafe(
176 def server(migration_thread_pool: Optional[Executor] =
None,
178 interceptors: Optional[Sequence[Any]] =
None,
179 options: Optional[ChannelArgumentType] =
None,
180 maximum_concurrent_rpcs: Optional[int] =
None,
182 """Creates a Server with which RPCs can be serviced.
185 migration_thread_pool: A futures.ThreadPoolExecutor to be used by the
186 Server to execute non-AsyncIO RPC handlers for migration purpose.
187 handlers: An optional list of GenericRpcHandlers used for executing RPCs.
188 More handlers may be added by calling add_generic_rpc_handlers any time
189 before the server is started.
190 interceptors: An optional list of ServerInterceptor objects that observe
191 and optionally manipulate the incoming RPCs before handing them over to
192 handlers. The interceptors are given control in the order they are
193 specified. This is an EXPERIMENTAL API.
194 options: An optional list of key-value pairs (:term:`channel_arguments` in gRPC runtime)
195 to configure the channel.
196 maximum_concurrent_rpcs: The maximum number of concurrent RPCs this server
197 will service before returning RESOURCE_EXHAUSTED status, or None to
199 compression: An element of grpc.compression, e.g.
200 grpc.compression.Gzip. This compression algorithm will be used for the
201 lifetime of the server unless overridden by set_compression. This is an
207 return Server(migration_thread_pool, ()
if handlers
is None else handlers,
208 ()
if interceptors
is None else interceptors,
209 ()
if options
is None else options, maximum_concurrent_rpcs,