refactor: enhance webhook delivery queue processing with configurable blocking

This commit is contained in:
Abhimanyu Saharan
2026-02-15 12:48:08 +05:30
parent 731fb9edac
commit e28496245b
6 changed files with 143 additions and 9 deletions

View File

@@ -78,12 +78,28 @@ def _coerce_datetime(raw: object | None) -> datetime:
return datetime.now(UTC)
def dequeue_task(queue_name: str, *, redis_url: str | None = None) -> QueuedTask | None:
def dequeue_task(
queue_name: str,
*,
redis_url: str | None = None,
block: bool = False,
block_timeout: float = 0,
) -> QueuedTask | None:
"""Pop one task envelope from the queue."""
client = _redis_client(redis_url=redis_url)
raw = cast(str | bytes | None, client.rpop(queue_name))
if raw is None:
return None
if block:
raw = cast(tuple[bytes | str, bytes | str] | None, client.brpop(queue_name, timeout=block_timeout))
if raw is None:
return None
raw = raw[1]
else:
raw = cast(str | bytes | None, client.rpop(queue_name))
if raw is None:
return None
return _decode_task(raw, queue_name)
def _decode_task(raw: str | bytes, queue_name: str) -> QueuedTask:
if isinstance(raw, bytes):
raw = raw.decode("utf-8")

View File

@@ -162,12 +162,12 @@ async def _process_single_item(item: QueuedInboundDelivery) -> None:
await session.commit()
async def flush_webhook_delivery_queue() -> None:
async def flush_webhook_delivery_queue(*, block: bool = False, block_timeout: float = 0) -> int:
"""Consume queued webhook events and notify board leads in a throttled batch."""
processed = 0
while True:
try:
item = dequeue_webhook_delivery()
item = dequeue_webhook_delivery(block=block, block_timeout=block_timeout)
except Exception:
logger.exception("webhook.dispatch.dequeue_failed")
continue
@@ -200,7 +200,9 @@ async def flush_webhook_delivery_queue() -> None:
)
requeue_if_failed(item)
time.sleep(settings.rq_dispatch_throttle_seconds)
logger.info("webhook.dispatch.batch_complete", extra={"count": processed})
if processed > 0:
logger.info("webhook.dispatch.batch_complete", extra={"count": processed})
return processed
def run_flush_webhook_delivery_queue() -> None:

View File

@@ -92,10 +92,19 @@ def enqueue_webhook_delivery(payload: QueuedInboundDelivery) -> bool:
return False
def dequeue_webhook_delivery() -> QueuedInboundDelivery | None:
def dequeue_webhook_delivery(
*,
block: bool = False,
block_timeout: float = 0,
) -> QueuedInboundDelivery | None:
"""Pop one queued webhook delivery payload."""
try:
task = dequeue_task(settings.rq_queue_name, redis_url=settings.rq_redis_url)
task = dequeue_task(
settings.rq_queue_name,
redis_url=settings.rq_redis_url,
block=block,
block_timeout=block_timeout,
)
if task is None:
return None
return _payload_from_task(task)