Documented server-specific details

This commit is contained in:
Vladimir Magamedov 2019-03-01 18:16:05 +02:00
parent 1024fe9937
commit 6617e3d5a2
4 changed files with 53 additions and 7 deletions

View File

@ -5,5 +5,5 @@ Reference
~~~~~~~~~
.. automodule:: grpclib.client
:members: Channel, Stream, UnaryUnaryMethod, UnaryStreamMethod,
StreamUnaryMethod, StreamStreamMethod
:members: Channel, Stream, UnaryUnaryMethod, UnaryStreamMethod,
StreamUnaryMethod, StreamStreamMethod

View File

@ -8,7 +8,7 @@ autoclass_content = 'both'
autodoc_member_order = 'bysource'
intersphinx_mapping = {
'python': ('https://docs.python.org/3.6', None),
'python': ('https://docs.python.org/3.7', None),
}
source_suffix = '.rst'

View File

@ -1,8 +1,53 @@
Server
======
Single :py:class:`~grpclib.server.Server` can serve arbitrary
number of services:
.. code-block:: python
server = Server([services], loop=loop)
To monitor health of your services you can use standard gRPC health checking
protocol, details are here: :doc:`health`.
There is a special gRPC reflection protocol to inspect running servers and call
their methods using command-line tools, details are here: :doc:`reflection`.
It is as simple as using curl.
And it is also important to handle server's exit properly:
.. code-block:: python
with graceful_exit([server]):
await server.start(host, port)
await server.wait_closed()
:py:func:`~grpclib.utils.graceful_exit` helps you handle ``SIGINT``
(during development) and ``SIGTERM`` (on production) signals.
When things become complicated you can start using
:py:class:`~python:contextlib.AsyncExitStack` and
:py:func:`~python:contextlib.asynccontextmanager` to manage lifecycle of your
application:
.. code-block:: python
async with AsyncExitStack() as stack:
db = await stack.enter_async_context(setup_db())
foo_svc = await stack.enter_async_context(setup_foo_svc())
bar_svc = BarService(db, foo_svc)
server = Server([bar_svc], loop=loop)
stack.enter_context(graceful_exit([server], loop=loop))
await server.start(host, port)
await server.wait_closed()
Reference
~~~~~~~~~
.. automodule:: grpclib.server
:members: Server, Stream
:members: Server, Stream
.. automodule:: grpclib.utils
:members: graceful_exit

View File

@ -156,15 +156,16 @@ def graceful_exit(servers, *, loop,
print('Server closed')
First stage calls ``server.close()`` and ``await server.wait_closed()``
should complete successfully without errors.
should complete successfully without errors. If server wasn't started yet,
second stage runs to prevent server start.
Second stage raises ``SystemExit`` exception, but you will receive
``asyncio.CancelledError`` in your ``async def main()`` coroutine. You
can use ``try..finally`` constructs or context-managers to properly handle
can use ``try..finally`` constructs and context-managers to properly handle
this error.
This context-manager is designed to work in cooperation with
:py:func:`python:asyncio.run` function, introduced in Python 3.7:
:py:func:`python:asyncio.run` function:
.. code-block:: python