refactor: own coalescer flush lifecycle

This commit is contained in:
jxxghp
2026-08-24 03:11:49 +08:00
parent e1230c0277
commit e768eb46fe
9 changed files with 71 additions and 7 deletions
+5
View File
@@ -950,6 +950,11 @@ _image_proxy_block_log_coalescer = EventCoalescer(
)
async def close_image_proxy_block_log_coalescer() -> None:
"""刷新图片代理阻断摘要,并等待已经启动的窗口 flush 任务。"""
await _image_proxy_block_log_coalescer.close()
async def _emit_image_proxy_block_warning(
*,
url: str,
+10 -1
View File
@@ -97,6 +97,7 @@ class EventCoalescer:
self._source = source
self._buckets: Dict[Hashable, _BucketState] = {}
self._is_flush_async = inspect.iscoroutinefunction(on_flush)
self._flush_tasks: set[asyncio.Task[None]] = set()
@property
def window_seconds(self) -> float:
@@ -144,6 +145,12 @@ class EventCoalescer:
if bucket.flush_handle is not None:
bucket.flush_handle.cancel()
await self._emit_summary_if_needed(key, bucket)
current_task = asyncio.current_task()
flush_tasks = tuple(
task for task in self._flush_tasks if task is not current_task
)
if flush_tasks:
await asyncio.gather(*flush_tasks, return_exceptions=True)
def _schedule_flush(self, key: Hashable) -> asyncio.TimerHandle:
"""
@@ -161,7 +168,9 @@ class EventCoalescer:
`loop.call_later` 到期回调:从事件循环里把异步 flush 任务接力起来。
"""
try:
asyncio.get_running_loop().create_task(self._flush_key(key))
task = asyncio.get_running_loop().create_task(self._flush_key(key))
self._flush_tasks.add(task)
task.add_done_callback(self._flush_tasks.discard)
except RuntimeError as exc:
# 事件循环已关闭等罕见路径:记录后丢弃,避免影响其它 bucket
self._log_debug(f"flush 调度失败,已忽略 key={key!r}: {exc}")
+2
View File
@@ -77,6 +77,7 @@ from app.application.messaging.agent import (
from app.application.security.user import configure_user_lookups
from app.application.security.auth import AuthService, configure_auth_service
from app.application.security.passkeys import PasskeyService, configure_passkey_service
from app.application.security.url import close_image_proxy_block_log_coalescer
from app.application.security.userconfig import (
UserConfigurationService,
configure_user_configuration,
@@ -594,6 +595,7 @@ async def stop_modules():
logger.error(f"关闭{name}失败:{err}")
return True
await run_step("图片代理安全日志合并器", close_image_proxy_block_log_coalescer)
await run_step("模块", lambda: ModuleManager().shutdown())
await run_step("事件消费", lambda: EventManager().stop_async())
await run_step("浏览器会话", close_browser_sessions)