Postgres engine: queues — Queue (validated constructor over the handle's QueueOpts stamps), the FOR UPDATE SKIP LOCKED claim (one statement, the pre-claim exhausted-reclaimable sweep in the atomic claim frame), JobHandle (one-shot ack/retry/fail in tx frames under the uniform validity predicate, absolute-reset heartbeat, engine-side equal-jitter backoff), dead-letter moves transactional (the #133 class excluded), worker-less ack_batch, unconditional cancel, dead-visible get_job, both-states+retention sweep, best-effort queue-channel wake, wake-driven claim loop pinned (task pg-engine-queues)
This commit is contained in:
1 parent
cb067bb4be
commit
3dd83791ff
7 files changed
+2640
-53
No files matched your search
+55
-34
@@ -192,20 +192,10 @@ impl PgTxHandle {
|
||||
.to_string()
|
||||
}
|
||||
|
||||
fn enqueue_row_sql(&self) -> String {
|
||||
format!(
|
||||
"INSERT INTO {} (queue, payload, run_at, priority, max_attempts,
|
||||
expires_at, created_at, visibility_timeout_s,
|
||||
backoff_base_s, dead_letter_retention_s)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
|
||||
RETURNING id",
|
||||
self.table(tables::JOB)
|
||||
)
|
||||
}
|
||||
|
||||
/// The plain-queue enqueue's shared write (the `enqueue_tx` /
|
||||
/// `outbox_enqueue_tx` INSERT), called with this handle's
|
||||
/// qualified job table.
|
||||
/// qualified job table — the module-level [`enqueue_row`]'s
|
||||
/// handle-side bridge.
|
||||
async fn enqueue_row(
|
||||
&self,
|
||||
client: &tokio_postgres::Client,
|
||||
@@ -214,31 +204,62 @@ impl PgTxHandle {
|
||||
opts: &EnqueueOpts,
|
||||
base: crate::resolution::Stamps,
|
||||
) -> Result<i64> {
|
||||
let now = crate::resolution::now_unix();
|
||||
let ResolvedEnqueue { run_at, expires_at } = resolve_enqueue_opts(now, opts);
|
||||
let stamps = stamps_with_override(base, opts);
|
||||
let row = client
|
||||
.query_one(
|
||||
&self.enqueue_row_sql(),
|
||||
&[
|
||||
&queue,
|
||||
&bytes,
|
||||
&run_at,
|
||||
&opts.priority,
|
||||
&stamps.max_attempts,
|
||||
&expires_at,
|
||||
&now,
|
||||
&stamps.visibility_timeout_s,
|
||||
&stamps.backoff_base_s,
|
||||
&stamps.dead_letter_retention_s,
|
||||
],
|
||||
)
|
||||
.await
|
||||
.map_err(pg_error)?;
|
||||
Ok(row.get(0))
|
||||
enqueue_row(client, &self.schema, queue, bytes, opts, base).await
|
||||
}
|
||||
}
|
||||
|
||||
/// The enqueue INSERT — the one owner of the plain-queue row write.
|
||||
/// The tx paths (`enqueue_tx` over the plain-queue defaults,
|
||||
/// `outbox_enqueue_tx` over the outbox's 60/5/5 set) and the auto-commit
|
||||
/// `Queue::enqueue` over the handle's `QueueOpts` ride it; one clock
|
||||
/// read per enqueue (the `now` the resolution and the write share).
|
||||
pub(crate) async fn enqueue_row(
|
||||
client: &tokio_postgres::Client,
|
||||
schema: &str,
|
||||
queue: &str,
|
||||
bytes: Vec<u8>,
|
||||
opts: &EnqueueOpts,
|
||||
base: crate::resolution::Stamps,
|
||||
) -> Result<i64> {
|
||||
let now = crate::resolution::now_unix();
|
||||
let ResolvedEnqueue { run_at, expires_at } = resolve_enqueue_opts(now, opts);
|
||||
let stamps = stamps_with_override(base, opts);
|
||||
let row = client
|
||||
.query_one(
|
||||
&enqueue_row_sql(schema),
|
||||
&[
|
||||
&queue,
|
||||
&bytes,
|
||||
&run_at,
|
||||
&opts.priority,
|
||||
&stamps.max_attempts,
|
||||
&expires_at,
|
||||
&now,
|
||||
&stamps.visibility_timeout_s,
|
||||
&stamps.backoff_base_s,
|
||||
&stamps.dead_letter_retention_s,
|
||||
],
|
||||
)
|
||||
.await
|
||||
.map_err(pg_error)?;
|
||||
Ok(row.get(0))
|
||||
}
|
||||
|
||||
/// The enqueue INSERT's SQL (schema-qualified job table).
|
||||
fn enqueue_row_sql(schema: &str) -> String {
|
||||
format!(
|
||||
"INSERT INTO {} (queue, payload, run_at, priority, max_attempts,
|
||||
expires_at, created_at, visibility_timeout_s,
|
||||
backoff_base_s, dead_letter_retention_s)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
|
||||
RETURNING id",
|
||||
QualifiedTable {
|
||||
schema,
|
||||
name: tables::JOB
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/// Encode a trait-crossing payload `Value` into the exact stored bytes
|
||||
/// (the serde_json serialization — ADR-020 §4). The notify carriage
|
||||
/// reuses it: the JSON serialization is valid UTF-8 text by
|
||||
|
||||
Reference in new issue
Block a user