trio-websocket
trio-websocket copied to clipboard
WebSocketServer.run() docs and shutdown
It will block until the server is accepting connections and then return a :class:
WebSocketServerobject
:returns: This method never returns unless cancelled.
These cannot both be true. The second remark matches the implementation, but the first remark is preferred. Currently, there doesn't seem to be a good way to cleanly shut down the server.
Ah, it looks like the server is returned via task.status.started(self). Perhaps the docs could be revised:
"When called by nursery.start(serve_websocket, ...) instead of nursery.start_soon, the running instance of WebSocketServer is returned."
With server = nursery.start(serve_websocket, ...), I believe my original comment still applies - there's no aclose() or sync close() on WebSocketServer for cleanly shutting down the server.
(I changed the title to WebSocketServer.run() but I see it also applies to serve_websocket().)
Here are the current docs with more context:
This method supports the Trio nursery start protocol:
server = await nursery.start(server.run, …). It will block until the server is accepting connections and then return a :class:WebSocketServerobject.
It does say that return of the WebSocketServer is done by way of start(), but could it be more clear? The reader is expected to be familiar with the Trio API and start_soon() vs. start().
Note that Trio library functions like serve_listeners() have the same API.
there's no aclose() or sync close() on WebSocketServer for cleanly shutting down the server
Trio has cancel scopes, and API implementations are able to encapsulate both synchronous and asynchronous shutdown. So the way you'd shut down the websocket server is to cancel the parent task. Note that there are two potential cancel points:
async with trio.open_nursery() as nursery:
# cancel if it takes more than 1 second to start accepting connections
with trio.fail_after(1):
await nursery.start(partial(serve_websocket, ...))
# sorry, this server will self-destruct after 5 minutes
await trio.sleep(5 * 60)
nursery.cancel_scope.cancel()
Everything should be cleanly shut down under such cancellations (as well as by Ctrl-C and SIGTERM)-- is there evidence otherwise?