Skip to content

Commit 755eac1

Browse files
committed
Simplify pattern for shutting down servers.
This avoids having to create manually a future. Also, it's robust to receiving multiple times the signal. Fix #1593.
1 parent 277f0f8 commit 755eac1

File tree

18 files changed

+69
-139
lines changed

18 files changed

+69
-139
lines changed

docs/faq/client.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ You can close the connection.
103103
Here's an example that terminates cleanly when it receives SIGTERM on Unix:
104104

105105
.. literalinclude:: ../../example/faq/shutdown_client.py
106-
:emphasize-lines: 11-13
106+
:emphasize-lines: 10-12
107107

108108
How do I disable TLS/SSL certificate verification?
109109
--------------------------------------------------

docs/faq/server.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ Exit the :func:`~serve` context manager.
310310
Here's an example that terminates cleanly when it receives SIGTERM on Unix:
311311

312312
.. literalinclude:: ../../example/faq/shutdown_server.py
313-
:emphasize-lines: 13-16,19
313+
:emphasize-lines: 14-16
314314

315315
How do I stop a server while keeping existing connections open?
316316
---------------------------------------------------------------

docs/howto/haproxy.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Run server processes
1515
Save this app to ``app.py``:
1616

1717
.. literalinclude:: ../../example/deployment/haproxy/app.py
18-
:emphasize-lines: 24
18+
:language: python
1919

2020
Each server process listens on a different port by extracting an incremental
2121
index from an environment variable set by Supervisor.

docs/howto/nginx.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Run server processes
1515
Save this app to ``app.py``:
1616

1717
.. literalinclude:: ../../example/deployment/nginx/app.py
18-
:emphasize-lines: 21,23
18+
:language: python
1919

2020
We'd like nginx to connect to websockets servers via Unix sockets in order to
2121
avoid the overhead of TCP for communicating between processes running in the

docs/intro/tutorial3.rst

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -120,14 +120,10 @@ that runs for each request. When it returns an HTTP response, websockets sends
120120
that response instead of opening a WebSocket connection. Here, requests to
121121
``/healthz`` return an HTTP 200 status code.
122122

123-
To catch the ``SIGTERM`` signal, ``main()`` creates a :class:`~asyncio.Future`
124-
called ``stop`` and registers a signal handler that sets the result of this
125-
future. The value of the future doesn't matter; it's only for waiting for
126-
``SIGTERM``.
127-
128-
Then, by using :func:`~asyncio.server.serve` as a context manager and exiting
129-
the context when ``stop`` has a result, ``main()`` ensures that the server
130-
closes connections cleanly and exits on ``SIGTERM``.
123+
``main()`` registers a signal handler that closes the server when receiving the
124+
``SIGTERM`` signal. Then, it waits for the server to be closed. Additionally,
125+
using :func:`~asyncio.server.serve` as a context manager ensures that the server
126+
will always be closed cleanly, even if the program crashes.
131127

132128
Deploy the WebSocket server
133129
---------------------------
@@ -157,14 +153,14 @@ Commit and push your changes:
157153
158154
$ git add .
159155
$ git commit -m "Deploy to Koyeb."
160-
[main ac96d65] Deploy to Koyeb.
161-
3 files changed, 18 insertions(+), 2 deletions(-)
156+
[main 4a4b6e9] Deploy to Koyeb.
157+
3 files changed, 15 insertions(+), 2 deletions(-)
162158
create mode 100644 Procfile
163159
create mode 100644 requirements.txt
164160
$ git push
165161
...
166162
To github.com:python-websockets/websockets-tutorial.git
167-
+ 6bd6032...ac96d65 main -> main
163+
+ 6bd6032...4a4b6e9 main -> main
168164
169165
Sign up or log in to Koyeb.
170166

@@ -239,7 +235,7 @@ Commit your changes:
239235
$ git push
240236
...
241237
To github.com:python-websockets/websockets-tutorial.git
242-
+ ac96d65...0903526 main -> main
238+
+ 4a4b6e9...968eaaa main -> main
243239
244240
Deploy the web application
245241
--------------------------

docs/topics/deployment.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,7 @@ Here's an example:
101101
:emphasize-lines: 13-16,19
102102

103103
When exiting the context manager, :func:`~asyncio.server.serve` closes all
104-
connections
105-
with code 1001 (going away). As a consequence:
104+
connections with code 1001 (going away). As a consequence:
106105

107106
* If the connection handler is awaiting
108107
:meth:`~asyncio.server.ServerConnection.recv`, it receives a

example/deployment/fly/app.py

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,10 @@ def health_check(connection, request):
1818

1919

2020
async def main():
21-
# Set the stop condition when receiving SIGTERM.
22-
loop = asyncio.get_running_loop()
23-
stop = loop.create_future()
24-
loop.add_signal_handler(signal.SIGTERM, stop.set_result, None)
25-
26-
async with serve(
27-
echo,
28-
host="",
29-
port=8080,
30-
process_request=health_check,
31-
):
32-
await stop
21+
async with serve(echo, "", 8080, process_request=health_check) as server:
22+
loop = asyncio.get_running_loop()
23+
loop.add_signal_handler(signal.SIGTERM, server.close)
24+
await server.wait_closed()
3325

3426

3527
if __name__ == "__main__":

example/deployment/haproxy/app.py

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,11 @@ async def echo(websocket):
1313

1414

1515
async def main():
16-
# Set the stop condition when receiving SIGTERM.
17-
loop = asyncio.get_running_loop()
18-
stop = loop.create_future()
19-
loop.add_signal_handler(signal.SIGTERM, stop.set_result, None)
20-
21-
async with serve(
22-
echo,
23-
host="localhost",
24-
port=8000 + int(os.environ["SUPERVISOR_PROCESS_NAME"][-2:]),
25-
):
26-
await stop
16+
port = 8000 + int(os.environ["SUPERVISOR_PROCESS_NAME"][-2:])
17+
async with serve(echo, "localhost", port) as server:
18+
loop = asyncio.get_running_loop()
19+
loop.add_signal_handler(signal.SIGTERM, server.close)
20+
await server.wait_closed()
2721

2822

2923
if __name__ == "__main__":

example/deployment/heroku/app.py

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,11 @@ async def echo(websocket):
1313

1414

1515
async def main():
16-
# Set the stop condition when receiving SIGTERM.
17-
loop = asyncio.get_running_loop()
18-
stop = loop.create_future()
19-
loop.add_signal_handler(signal.SIGTERM, stop.set_result, None)
20-
21-
async with serve(
22-
echo,
23-
host="",
24-
port=int(os.environ["PORT"]),
25-
):
26-
await stop
16+
port = int(os.environ["PORT"])
17+
async with serve(echo, "localhost", port) as server:
18+
loop = asyncio.get_running_loop()
19+
loop.add_signal_handler(signal.SIGTERM, server.close)
20+
await server.wait_closed()
2721

2822

2923
if __name__ == "__main__":

example/deployment/koyeb/app.py

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,11 @@ def health_check(connection, request):
1919

2020

2121
async def main():
22-
# Set the stop condition when receiving SIGINT.
23-
loop = asyncio.get_running_loop()
24-
stop = loop.create_future()
25-
loop.add_signal_handler(signal.SIGINT, stop.set_result, None)
26-
27-
async with serve(
28-
echo,
29-
host="",
30-
port=int(os.environ["PORT"]),
31-
process_request=health_check,
32-
):
33-
await stop
22+
port = int(os.environ["PORT"])
23+
async with serve(echo, "", port, process_request=health_check) as server:
24+
loop = asyncio.get_running_loop()
25+
loop.add_signal_handler(signal.SIGINT, server.close)
26+
await server.wait_closed()
3427

3528

3629
if __name__ == "__main__":

0 commit comments

Comments
 (0)