@@ -405,18 +405,25 @@ def start_connection_handler(self, connection: ServerConnection) -> None:
405405 # but before it starts executing.
406406 self .handlers [connection ] = self .loop .create_task (self .conn_handler (connection ))
407407
408- def close (self , close_connections : bool = True ) -> None :
408+ def close (
409+ self ,
410+ close_connections : bool = True ,
411+ code : CloseCode | int = CloseCode .GOING_AWAY ,
412+ reason : str = "" ,
413+ ) -> None :
409414 """
410415 Close the server.
411416
412417 * Close the underlying :class:`asyncio.Server`.
413- * When ``close_connections`` is :obj:`True`, which is the default,
414- close existing connections. Specifically:
418+ * When ``close_connections`` is :obj:`True`, which is the default, close
419+ existing connections. Specifically:
415420
416421 * Reject opening WebSocket connections with an HTTP 503 (service
417422 unavailable) error. This happens when the server accepted the TCP
418423 connection but didn't complete the opening handshake before closing.
419- * Close open WebSocket connections with close code 1001 (going away).
424+ * Close open WebSocket connections with code 1001 (going away).
425+ ``code`` and ``reason`` can be customized, for example to use code
426+ 1012 (service restart).
420427
421428 * Wait until all connection handlers terminate.
422429
@@ -425,16 +432,21 @@ def close(self, close_connections: bool = True) -> None:
425432 """
426433 if self .close_task is None :
427434 self .close_task = self .get_loop ().create_task (
428- self ._close (close_connections )
435+ self ._close (close_connections , code , reason )
429436 )
430437
431- async def _close (self , close_connections : bool ) -> None :
438+ async def _close (
439+ self ,
440+ close_connections : bool = True ,
441+ code : CloseCode | int = CloseCode .GOING_AWAY ,
442+ reason : str = "" ,
443+ ) -> None :
432444 """
433445 Implementation of :meth:`close`.
434446
435447 This calls :meth:`~asyncio.Server.close` on the underlying
436448 :class:`asyncio.Server` object to stop accepting new connections and
437- then closes open connections with close code 1001 .
449+ then closes open connections.
438450
439451 """
440452 self .logger .info ("server closing" )
@@ -447,11 +459,13 @@ async def _close(self, close_connections: bool) -> None:
447459 # details. This workaround can be removed when dropping Python < 3.11.
448460 await asyncio .sleep (0 )
449461
462+ # After server.close(), handshake() closes OPENING connections with an
463+ # HTTP 503 error.
464+
450465 if close_connections :
451- # Close OPEN connections with close code 1001. After server.close(),
452- # handshake() closes OPENING connections with an HTTP 503 error.
466+ # Close OPEN connections with code 1001 by default.
453467 close_tasks = [
454- asyncio .create_task (connection .close (1001 ))
468+ asyncio .create_task (connection .close (code , reason ))
455469 for connection in self .handlers
456470 if connection .protocol .state is not CONNECTING
457471 ]
0 commit comments