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

@@ -23,6 +23,7 @@ pub mod log_sink;
pub mod modules;
pub mod outbox_writer;
pub mod pubsub;
pub mod queue;
pub mod realtime;
pub mod realtime_authority;
pub mod route;
@@ -53,8 +54,8 @@ pub use files::{
};
pub use http::{HttpError, HttpRequest, HttpResponse, HttpService, NoopHttpService};
pub use ids::{
AdminUserId, ApiKeyId, AppId, AppUserId, ExecutionId, InvitationId, RequestId, ScriptId,
TriggerId,
AdminUserId, ApiKeyId, AppId, AppUserId, ExecutionId, InvitationId, QueueMessageId, RequestId,
ScriptId, TriggerId,
};
pub use inbox::{
InboxDeliveryOutcome, InboxFailureKind, InboxResolver, InboxResult, NoopInboxResolver,
@@ -66,6 +67,7 @@ pub use outbox_writer::{HttpDispatchPayload, NewHttpOutbox, OutboxWriter, Outbox
pub use pubsub::{
topic_matches, validate_topic_pattern, NoopPubsubService, PubsubError, PubsubService,
};
pub use queue::{EnqueueOpts, NoopQueueService, QueueError, QueueService};
pub use realtime::{BroadcasterError, NoopRealtimeBroadcaster, RealtimeBroadcaster, RealtimeEvent};
pub use realtime_authority::{DenyAllRealtimeAuthority, RealtimeAuthority, SubscribeDenied};
pub use route::{DispatchMode, HostKind, PathKind, Route};