Skip to the content.

Task 86 — Backpressure, bounded channels, and DLQ/requeue fixes

Phase: 5 Initiative: 46 Status: done Owner: — Slug: backpressure-bounded-channels-dlq

Goal

Нет backpressure нигде: все channels unbounded, handler dispatch fire-and-forget. DLQ/requeue имеют bugs в in-process queue.

Проблемы:

  1. No backpressure: InMemoryEventBus.cs:36,49 — TryWrite to unbounded channels. InProcessMeshBus.cs:47 — fire-and-forget handler invocation, no limit on concurrent handlers.
  2. InProcessTaskQueue visibility timeout stub (Issue 34): InProcessTaskQueue.cs:276-281 — ReEnqueueTimedOut timer — no-op; timed-out tasks never re-enqueued.
  3. InProcessTaskQueue DLQ requeue broken (Issue 35): InProcessTaskQueue.cs:259-262 — RequeueDeadLetterAsync builds new DLQ but never replaces old one in _dlqs — DLQ item not removed.
  4. RedisTaskQueue O(N) scan (Issue 37): RedisTaskQueue.cs:186-226 — AckAsync/FailAsync scan all in-flight keys via server.Keys(pattern:...) per ack — O(N) per operation.

Acceptance criteria

Sub-tasks

Scope / Likely files

src/agent/HerculesBus/InMemory/InMemoryEventBus.cs, src/agent/Mesh/InProcess/InProcessMeshBus.cs, src/agent/Mesh/InProcess/InProcessTaskQueue.cs, src/agent/Mesh/Backends/Redis/RedisTaskQueue.cs, src/agent/appsettings.json

Implementation notes

Реализовано в коммите (см. git log):

Validation

Dependencies

Risks / Rollback

Bounded channels with WaitAsync могут deadlock если subscriber slower than publisher; configurable timeout + drop policy. In-process visibility timeout — background timer overhead. Rollback: вернуть unbounded channels (но OOM риск под нагрузкой).