PgQueueListener: - Dedicated asyncpg connection outside the SQLAlchemy pool (LISTEN needs a persistent connection; pooled connections check in/out). - Exposes wait_for_work(timeout) — resolves on NOTIFY or timeout, whichever fires first. The worker treats both wakes identically. - asyncpg_dsn_from_sqlalchemy_url strips the +asyncpg driver segment and percent-decodes the password so the same URL in IX_POSTGRES_URL works for both SQLAlchemy and raw asyncpg. app.py lifespan now also spawns the listener alongside the worker; both are gated on spawn_worker=True so REST-only tests stay fast. 2 new integration tests: NOTIFY path (wake within 2 s despite 60 s poll) + missed-NOTIFY path (fallback poll recovers within 5 s). 33 integration tests total, 209 unit. Forgejo Actions trigger is flaky; local verification is the gate. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
15 lines
595 B
Python
15 lines
595 B
Python
"""Postgres queue adapter — ``LISTEN ix_jobs_new`` + 10 s fallback poll.
|
|
|
|
This is a secondary transport: a direct-SQL writer can insert a row and
|
|
``NOTIFY ix_jobs_new, '<job_id>'`` and the worker wakes up within the roundtrip
|
|
time rather than the 10 s fallback poll. The REST adapter doesn't need the
|
|
listener because the worker is already running in-process; this exists for
|
|
external callers who bypass the REST API.
|
|
"""
|
|
|
|
from ix.adapters.pg_queue.listener import (
|
|
PgQueueListener,
|
|
asyncpg_dsn_from_sqlalchemy_url,
|
|
)
|
|
|
|
__all__ = ["PgQueueListener", "asyncpg_dsn_from_sqlalchemy_url"]
|