Skip to content

fix(queue): named queues collide on a shared local Deno KV database — listeners consume each other's messages #1682

Description

@rickylabs

Found during the #1678 harness run (drift D-5) and reproduced deterministically; the run's IMPL-EVAL verified the source claims.

Behavior

With the default local Deno KV provider, createQueue('jobs') and createQueue('tasks') on the same KV database each open their own connection and register their own kv.listenQueue handler. Deno KV has one queue per database, and the adapter envelope carries no queue name (packages/queue/adapters/_envelope.tspayload/headers/messageId/enqueuedAt/deliveryCount only; packages/queue/adapters/deno-kv.adapter.ts does no name filtering). Messages are therefore delivered to whichever listener's connection wins.

Observed: with a combined Worker (jobs listener + task listener) on one local KV file, the jobs listener consumed tasks messages — Processing job 'undefined' … Job 'undefined' failed: Workers KV key contains unsupported part: undefined — and the message was lost to the task listener (no retry reached it). Reproduction detail in the #1678 run dir (worklog.md S5, bench/harness/run-series.ts header comment).

Scope

  • Redis/RabbitMQ providers are unaffected (real named queues); KV-polling adapter unexamined.
  • Affects DB-less local dev (--db none scaffolds) running worker + scheduler/task listeners in one process on the default local KV — the quickstart-shaped setup.

Fix directions (either closes it)

  1. Add the queue name to the envelope and have each KV listener filter + re-enqueue (or nack) foreign-name envelopes; or
  2. Namespace per-queue delivery on Deno KV (e.g. one KV connection per queue name with keyspace-prefixed queue payloads and a single shared listenQueue dispatcher that routes by envelope name).

Acceptance

  • Two createQueue instances with different names on one local Deno KV database deliver each message only to its own name's listener (regression test)
  • Combined worker process (jobs + tasks listeners) on local KV processes a task message end-to-end without the jobs listener consuming it

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions