45 lines
1.7 KiB
Python
45 lines
1.7 KiB
Python
"""Shared queue that bridges Flask request threads to the bot's async loop.
|
|
|
|
Module-level, not per-instance: the supervisor replaces the bot object on every
|
|
restart (discord.py cannot reuse a client whose run() has returned). A queue
|
|
living on the old object would be discarded with it, taking every pending
|
|
notification along.
|
|
"""
|
|
|
|
import logging
|
|
from queue import Empty, Queue # noqa: F401 — re-exported for bot.py
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
#: The shared queue instance.
|
|
message_queue: Queue = Queue()
|
|
|
|
|
|
def enqueue(kind: str, data: dict, *, description: str) -> bool:
|
|
"""Hand one notification to the bot thread. Never raises.
|
|
|
|
The three public senders were the same fifteen lines three times, each with
|
|
its own blanket catch. There is one now, and it is the only place where
|
|
breadth is a property of the caller rather than of the failure: this runs
|
|
in a Flask request thread, and the work the notification announces is
|
|
already committed. The meeting is booked whether or not Discord hears about
|
|
it, so a failure here must not become a 500 on a page whose job is done.
|
|
|
|
What it is *not* is somewhere to lose a defect: the traceback is logged
|
|
and the caller is told False.
|
|
|
|
Args:
|
|
kind: Event type name ('one_on_one_request', 'schedule_addition', …).
|
|
data: Payload dict.
|
|
description: Human-readable label for the log message.
|
|
|
|
Returns:
|
|
True on success, False on failure.
|
|
"""
|
|
try:
|
|
message_queue.put({'type': kind, 'data': data})
|
|
except Exception: # a notification must never fail the request that caused it # noqa: BLE001
|
|
_logger.exception('Could not queue %s', description)
|
|
return False
|
|
return True
|