feat(v1.1.9): QueueRepo trait + Postgres impl + shared queue.rs

- shared/queue.rs: QueueService trait (enqueue / depth / depth_pending),
  EnqueueOpts, QueueError, NoopQueueService. Methods derive app_id from
  cx.app_id — no script-passed app_id. The handle-less surface mirrors
  pubsub (queues are the grouping unit).
- shared/ids.rs: QueueMessageId.
- manager-core/queue_repo.rs: PostgresQueueRepo with:
   - enqueue(NewQueueMessage) — single INSERT
   - claim(app_id, queue_name) — atomic UPDATE WHERE id = (SELECT … FOR
     UPDATE SKIP LOCKED LIMIT 1) RETURNING — the single-round-trip claim
     from the design notes
   - ack(id, claim_token) — DELETE WHERE id AND claim_token (lease check)
   - nack(id, claim_token, retry_delay) — clear claim + set deliver_after
   - reclaim_visibility_timeouts() — periodic UPDATE joining triggers +
     queue_trigger_details, clears claims older than per-queue
     visibility_timeout_secs
   - depth / depth_pending / list_for_app (dashboard read-only)
   - dead_letter(...) — atomic move to dead_letters + DELETE from
     queue_messages, in one transaction. Uses a JSON payload shaped the
     same as TriggerEvent::Queue so the existing fan_out_dead_letter
     path delivers the original to registered dead_letter triggers
     without special-casing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
MechaCat02
2026-06-06 19:12:33 +02:00
parent 9ce3c4c704
commit f6c7ab6f7c
5 changed files with 572 additions and 2 deletions

View File

@@ -55,6 +55,7 @@ pub mod outbox_repo;
pub mod principal_resolver;
pub mod pubsub_repo;
pub mod pubsub_service;
pub mod queue_repo;
pub mod realtime_authority;
pub mod repo;
pub mod route_admin;