Implemented Python 3.12 support
This commit is contained in:
parent
9bca0866fa
commit
308b353ab4
|
@ -24,7 +24,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
|
||||
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/cache@v3
|
||||
|
|
|
@ -625,6 +625,7 @@ class Server(_GC):
|
|||
self._config = config.__for_server__()
|
||||
|
||||
self._server: Optional[asyncio.AbstractServer] = None
|
||||
self._server_closed_fut: Optional[asyncio.Future[None]] = None
|
||||
self._handlers: Set[Handler] = set()
|
||||
|
||||
self.__dispatch__ = _DispatchServerEvents()
|
||||
|
@ -703,7 +704,6 @@ class Server(_GC):
|
|||
self._protocol_factory, path, sock=sock, backlog=backlog,
|
||||
ssl=ssl
|
||||
)
|
||||
|
||||
else:
|
||||
# FIXME: Not all union combinations were tried because there are
|
||||
# too many unions
|
||||
|
@ -715,15 +715,18 @@ class Server(_GC):
|
|||
backlog=backlog, ssl=ssl,
|
||||
reuse_address=reuse_address, reuse_port=reuse_port
|
||||
)
|
||||
self._server_closed_fut = self._loop.create_future()
|
||||
|
||||
def close(self) -> None:
|
||||
"""Stops accepting new connections, cancels all currently running
|
||||
requests. Request handlers are able to handle `CancelledError` and
|
||||
exit properly.
|
||||
"""
|
||||
if self._server is None:
|
||||
if self._server is None or self._server_closed_fut is None:
|
||||
raise RuntimeError('Server is not started')
|
||||
self._server.close()
|
||||
if not self._server_closed_fut.done():
|
||||
self._server_closed_fut.set_result(None)
|
||||
for handler in self._handlers:
|
||||
handler.close()
|
||||
|
||||
|
@ -731,8 +734,9 @@ class Server(_GC):
|
|||
"""Coroutine to wait until all existing request handlers will exit
|
||||
properly.
|
||||
"""
|
||||
if self._server is None:
|
||||
if self._server is None or self._server_closed_fut is None:
|
||||
raise RuntimeError('Server is not started')
|
||||
await self._server_closed_fut
|
||||
await self._server.wait_closed()
|
||||
if self._handlers:
|
||||
await asyncio.wait({
|
||||
|
|
|
@ -106,6 +106,7 @@ class ChannelFor:
|
|||
status_details_codec=self._status_details_codec,
|
||||
)
|
||||
self._server._server = _Server()
|
||||
self._server._server_closed_fut = self._server._loop.create_future()
|
||||
self._server_protocol = self._server._protocol_factory()
|
||||
|
||||
self._channel = Channel(
|
||||
|
|
|
@ -52,6 +52,8 @@ asyncio_mode = auto
|
|||
filterwarnings =
|
||||
error
|
||||
ignore:.*pkg_resources.*:DeprecationWarning
|
||||
ignore:.*google.*:DeprecationWarning
|
||||
ignore:.*utcfromtimestamp.*:DeprecationWarning
|
||||
ignore::ResourceWarning
|
||||
|
||||
[coverage:run]
|
||||
|
|
|
@ -167,6 +167,6 @@ class ClientServer:
|
|||
return handler, stub
|
||||
|
||||
async def __aexit__(self, *exc_info):
|
||||
self.channel.close()
|
||||
self.server.close()
|
||||
await self.server.wait_closed()
|
||||
self.channel.close()
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
import asyncio
|
||||
|
||||
import pytest
|
||||
|
||||
from grpclib.server import Server
|
||||
|
||||
|
||||
async def serve_forever(server):
|
||||
await server.start('127.0.0.1')
|
||||
await server.wait_closed()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_wait_closed(loop: asyncio.AbstractEventLoop):
|
||||
server = Server([])
|
||||
task = loop.create_task(serve_forever(server))
|
||||
done, pending = await asyncio.wait([task], timeout=0.1)
|
||||
assert pending and not done
|
||||
server.close()
|
||||
done, pending = await asyncio.wait([task], timeout=0.1)
|
||||
assert done and not pending
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_close_twice():
|
||||
server = Server([])
|
||||
await server.start('127.0.0.1')
|
||||
server.close()
|
||||
server.close()
|
||||
await server.wait_closed()
|
Loading…
Reference in New Issue