@@ -405,18 +405,25 @@ def start_connection_handler(self, connection: ServerConnection) -> None:
405
405
# but before it starts executing.
406
406
self .handlers [connection ] = self .loop .create_task (self .conn_handler (connection ))
407
407
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 :
409
414
"""
410
415
Close the server.
411
416
412
417
* 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:
415
420
416
421
* Reject opening WebSocket connections with an HTTP 503 (service
417
422
unavailable) error. This happens when the server accepted the TCP
418
423
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).
420
427
421
428
* Wait until all connection handlers terminate.
422
429
@@ -425,16 +432,21 @@ def close(self, close_connections: bool = True) -> None:
425
432
"""
426
433
if self .close_task is None :
427
434
self .close_task = self .get_loop ().create_task (
428
- self ._close (close_connections )
435
+ self ._close (close_connections , code , reason )
429
436
)
430
437
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 :
432
444
"""
433
445
Implementation of :meth:`close`.
434
446
435
447
This calls :meth:`~asyncio.Server.close` on the underlying
436
448
:class:`asyncio.Server` object to stop accepting new connections and
437
- then closes open connections with close code 1001 .
449
+ then closes open connections.
438
450
439
451
"""
440
452
self .logger .info ("server closing" )
@@ -447,11 +459,13 @@ async def _close(self, close_connections: bool) -> None:
447
459
# details. This workaround can be removed when dropping Python < 3.11.
448
460
await asyncio .sleep (0 )
449
461
462
+ # After server.close(), handshake() closes OPENING connections with an
463
+ # HTTP 503 error.
464
+
450
465
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.
453
467
close_tasks = [
454
- asyncio .create_task (connection .close (1001 ))
468
+ asyncio .create_task (connection .close (code , reason ))
455
469
for connection in self .handlers
456
470
if connection .protocol .state is not CONNECTING
457
471
]
0 commit comments