Problem
The poller entrypoint runs the on-demand drain loop and full poll loop concurrently. Queue rows are atomically claimed, but there is no per-tenant lease/advisory lock around a full tenant poll.
Impact
Drain and scheduled runs, or multiple poller containers, can fetch and verify the same listings for the same tenant at the same time. Unique constraints limit duplicate rows, but external call volume and log noise can grow quickly.
References
docker/poller-entrypoint.sh
src/applytrack/worker.py
src/applytrack/poll.py
Acceptance criteria
- A tenant can have at most one active poll run across drain/full/multi-container execution.
- Use
pg_try_advisory_lock or a durable lease table.
- Skipped locked tenants are logged at info/debug and retried later.
- Tests cover overlapping drain/full behavior.
Problem
The poller entrypoint runs the on-demand drain loop and full poll loop concurrently. Queue rows are atomically claimed, but there is no per-tenant lease/advisory lock around a full tenant poll.
Impact
Drain and scheduled runs, or multiple poller containers, can fetch and verify the same listings for the same tenant at the same time. Unique constraints limit duplicate rows, but external call volume and log noise can grow quickly.
References
docker/poller-entrypoint.shsrc/applytrack/worker.pysrc/applytrack/poll.pyAcceptance criteria
pg_try_advisory_lockor a durable lease table.