Skip to content

Commit 142b710

Browse files
author
coke
committed
fix(admin): rewrite server stats logic to ensure single coroutine execution and update version to 0.3.5
1 parent 988ad63 commit 142b710

2 files changed

Lines changed: 61 additions & 2 deletions

File tree

fastapi_sio_di/async_admin.py

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,74 @@
1+
import time
12
from typing import Any, List
3+
24
from socketio.async_admin import (
35
InstrumentedAsyncServer as SocketIOInstrumentedAsyncServer,
6+
HOSTNAME,
7+
PID,
48
)
59

610
from .params import SID, Environ
711

812

913
class InstrumentedAsyncServer(SocketIOInstrumentedAsyncServer):
1014

15+
def __init__(self, *args, **kwargs):
16+
super().__init__(*args, **kwargs)
17+
self._stats_task_running = False
18+
1119
async def admin_connect(self, sid: SID, environ: Environ, client_auth: Any):
1220
return await super().admin_connect(sid=sid, environ=environ, client_auth=client_auth)
1321

1422
async def admin_disconnect(self, sid: SID, namespace: str, close: bool, room_filter: List[str] = None):
15-
return await super().admin_disconnect(sid, namespace=namespace, close=close, room_filter=room_filter)
23+
return await super().admin_disconnect(sid, namespace=namespace, close=close, room_filter=room_filter)
24+
25+
async def _emit_server_stats(self):
26+
"""重写统计信息推送逻辑,确保全局只有一个协程在跑"""
27+
if self._stats_task_running:
28+
return
29+
30+
self._stats_task_running = True
31+
try:
32+
start_time = time.time()
33+
namespaces = list(self.sio.handlers.keys())
34+
namespaces.sort()
35+
36+
while not self.stop_stats_event.is_set():
37+
await self.sio.sleep(self.server_stats_interval)
38+
39+
# 检查是否还有管理员在监听,如果没有可以考虑退出(可选优化)
40+
if not self.sio.manager.rooms.get(self.admin_namespace, {}).get(None):
41+
break
42+
43+
await self.sio.emit(
44+
"server_stats",
45+
{
46+
"serverId": self.server_id,
47+
"hostname": HOSTNAME,
48+
"pid": PID,
49+
"uptime": time.time() - start_time,
50+
"clientsCount": len(self.sio.eio.sockets),
51+
"pollingClientsCount": len(
52+
[s for s in self.sio.eio.sockets.values() if not s.upgraded]
53+
),
54+
"aggregatedEvents": self.event_buffer.get_and_clear(),
55+
"namespaces": [
56+
{
57+
"name": nsp,
58+
"socketsCount": len(
59+
self.sio.manager.rooms.get(nsp, {None: []}).get(
60+
None, []
61+
)
62+
),
63+
}
64+
for nsp in namespaces
65+
],
66+
},
67+
namespace=self.admin_namespace,
68+
)
69+
70+
while self.admin_queue:
71+
event, args = self.admin_queue.pop(0)
72+
await self.sio.emit(event, args, namespace=self.admin_namespace)
73+
finally:
74+
self._stats_task_running = False

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "fastapi-sio-di"
3-
version = "0.3.4"
3+
version = "0.3.5"
44
description = "FastAPI-SIO-DI is a library tailored for integrating Socket.IO with FastAPI. It allows you to develop real-time WebSocket applications using the familiar FastAPI style (Dependency Injection, Pydantic models)."
55
requires-python = ">=3.10"
66
dependencies = [

0 commit comments

Comments
 (0)