|
1 | 1 | import asyncio |
2 | 2 | import time |
3 | | -import weakref |
4 | 3 |
|
5 | 4 | import aiohttp |
6 | 5 | from aiohttp import web |
|
10 | 9 | from ..scoring import Scoreboard |
11 | 10 |
|
12 | 11 | scoreboards: list[Scoreboard] = [Scoreboard()] |
13 | | -ws_connections = weakref.WeakSet() |
| 12 | +ws_connections: set[web.WebSocketResponse] = set() |
14 | 13 |
|
15 | 14 |
|
16 | 15 | async def on_startup(app): |
@@ -40,16 +39,31 @@ def on_solve(sender, user, cid): |
40 | 39 | if team.startswith("_"): |
41 | 40 | return |
42 | 41 | scoreboards.append(scoreboards[-1].solve(team, r8.challenges[cid], time.time())) |
| 42 | + |
| 43 | + data = scoreboards[-1].to_json() |
43 | 44 | for ws in ws_connections: |
44 | | - try: |
45 | | - asyncio.create_task(ws.send_json(scoreboards[-1].to_json())) |
46 | | - except ConnectionError: |
47 | | - pass |
| 45 | + asyncio.create_task(send_task(ws, data)) |
| 46 | + |
| 47 | + |
| 48 | +async def send_task(ws: web.WebSocketResponse, data) -> None: |
| 49 | + try: |
| 50 | + await ws.send_json(data) |
| 51 | + except ConnectionError: |
| 52 | + pass |
48 | 53 |
|
49 | 54 |
|
50 | 55 | async def on_shutdown(app): |
51 | | - for ws in ws_connections: |
52 | | - await ws.close(code=aiohttp.WSCloseCode.GOING_AWAY, message='Server shutdown') |
| 56 | + await asyncio.gather(*[ |
| 57 | + shutdown_task(ws) |
| 58 | + for ws in ws_connections |
| 59 | + ]) |
| 60 | + |
| 61 | + |
| 62 | +async def shutdown_task(ws: web.WebSocketResponse) -> None: |
| 63 | + try: |
| 64 | + await ws.close(code=aiohttp.WSCloseCode.GOING_AWAY, message=b'server shutdown') |
| 65 | + except ConnectionError: |
| 66 | + pass |
53 | 67 |
|
54 | 68 |
|
55 | 69 | routes = web.RouteTableDef() |
@@ -91,8 +105,7 @@ async def get_updates(user: str, request: web.Request): |
91 | 105 | elif msg.type == aiohttp.WSMsgType.ERROR: |
92 | 106 | r8.echo("scoreboard", f'ws connection closed with exception {ws.exception()}') |
93 | 107 | finally: |
94 | | - ws_connections.discard(ws) |
95 | | - # r8.echo('scoreboard', 'websocket connection closed') |
| 108 | + ws_connections.remove(ws) |
96 | 109 | return ws |
97 | 110 |
|
98 | 111 |
|
|
0 commit comments