refactor: ack panel webhooks immediately and run event handling in bounded background task

This commit is contained in:
3252a8
2026-05-16 00:02:22 +03:00
parent 87f9e23bae
commit 55dce99d34
+22 -1
View File
@@ -1,3 +1,4 @@
import asyncio
import hashlib
import hmac
import json
@@ -29,6 +30,10 @@ EVENT_MAP = {
class PanelWebhookService:
# Cap parallel background event handlers so an expiry burst from the panel
# cannot exhaust the DB pool or the YooKassa client.
_MAX_CONCURRENT_EVENTS = 50
def __init__(
self,
bot: Bot,
@@ -42,6 +47,7 @@ class PanelWebhookService:
self.i18n = i18n
self.async_session_factory = async_session_factory
self.panel_service = panel_service
self._event_semaphore = asyncio.Semaphore(self._MAX_CONCURRENT_EVENTS)
if not self.settings.PANEL_WEBHOOK_SECRET:
logging.error(
"PANEL_WEBHOOK_SECRET is not configured. Panel webhooks will be rejected."
@@ -243,9 +249,24 @@ class PanelWebhookService:
telegram_id if telegram_id is not None else "N/A",
)
await self.handle_event(event_name, user_data)
# Acknowledge immediately so the panel does not retry while we run
# auto-renew charges, DB lookups and SMTP. Heavy work is bounded by a
# semaphore to survive expiry bursts.
asyncio.create_task(
self._run_event_in_background(event_name, user_data),
name=f"panel_event_{event_name}",
)
return web.Response(status=200, text="ok")
async def _run_event_in_background(self, event_name: str, user_payload: dict) -> None:
async with self._event_semaphore:
try:
await self.handle_event(event_name, user_payload)
except Exception:
logging.exception(
"Panel webhook background handler failed for event %s", event_name
)
async def panel_webhook_route(request: web.Request):
service: PanelWebhookService = request.app["panel_webhook_service"]