Task 66 — Абстракция mesh-бэкендов
Phase: 4
Initiative: 26
Status: done
Owner: —
Slug: mesh-backends-abstraction
Goal
Интерфейсы IMeshBus, ITaskQueue и IMeshStateStore отделяют mesh-оркестрацию от конкретных бэкендов. Single-host mesh продолжает работать с in-process очередями и SQLite по умолчанию. Бэкенды подключаются через dependency injection и не влияют на публичный API агента.
Acceptance criteria
IMeshBusinterface with Publish/Subscribe/RequestReply semanticsITaskQueueinterface with Enqueue/Dequeue/Ack/DLQ semanticsIMeshStateStoreinterface with Get/Set/CompareAndSet/Watch semanticsInProcessMeshBus— Channel-based pub/sub + request/reply (default)InProcessTaskQueue— ConcurrentQueue-based task queue (default)InProcessMeshStateStore— ConcurrentDictionary-based state store (default)- Interfaces live in
src/agent/Mesh/Abstractions/ - In-process impls live in
src/agent/Mesh/InProcess/ - All abstractions registered in
MeshServiceCollectionExtensions - Unit tests for all three interfaces covering happy path + error cases
dotnet buildpasses;dotnet testpasses
Sub-tasks (implementation checklist)
- Define IMeshBus with Publish/Subscribe/RequestReply/IsHealthy
- Define ITaskQueue with Enqueue/Dequeue/Ack/Fail/DLQ + MeshTask/QueuedTask records
- Define IMeshStateStore with Get/Set/CompareAndSet/Delete/Exists/Increment/Watch/ScanKeys/IsHealthy + StoredValue record
- Implement InProcessMeshBus (Channel-based pub/sub, ConcurrentDictionary subscribers, reply routing via TCS)
- Implement InProcessTaskQueue (ConcurrentQueue + Timer for visibility timeout, DLQ, retry with delay, ULID IDs)
- Implement InProcessMeshStateStore (ConcurrentDictionary + Timer for TTL cleanup, Channel for Watch)
- Register all three as singleton defaults in MeshServiceCollectionExtensions
- Write InProcessMeshBusTests (9 tests: BackendKind, IsHealthy, Publish, Subscribe fan-out, unsubscribe, RequestReply, timeout, Dispose)
- Write InProcessTaskQueueTests (14 tests: BackendKind, Enqueue, Dequeue, FIFO, Ack, Fail+retry, Fail→DLQ, DLQ read, IsHealthy, Dispose)
- Write InProcessMeshStateStoreTests (16 tests: BackendKind, Get/Set, CAS, Delete, Exists, Increment, Watch, ScanKeys, IsHealthy, Dispose)
- Fix bug: missing
ScheduleReEnqueueAsyncmethod in InProcessTaskQueue (broken ContinueWith state object) - Fix bug: DLQ name mutation in FailAsync (
queueName→queueName + "-dlq"caused_dlqs["dlq-q-dlq"]vs_dlqs["dlq-q-dlq-dlq"]mismatch)
Validation
dotnet build src/agent/Hercules.csproj → 0 errors
dotnet test --filter "FullyQualifiedName~InProcess"
→ Passed: 42, Failed: 0
Completion note
Implemented three mesh backend abstractions (IMeshBus, ITaskQueue, IMeshStateStore) with in-process defaults:
- IMeshBus: Channel-based pub/sub + request/reply with correlation-ID routing via TaskCompletionSource
- ITaskQueue: ConcurrentQueue with visibility timeout via Timer, DLQ, retry with delay, ULID IDs; fixes: missing
ScheduleReEnqueueAsynchelper, DLQ key mutation causing wrong queue lookup - IMeshStateStore: ConcurrentDictionary with version-based optimistic locking, TTL cleanup, Channel-based Watch
- All registered as singleton defaults in MeshServiceCollectionExtensions (lines 440-445)
- 42 unit tests covering happy path and error cases
Scope / Likely files
src/agent/Mesh/Abstractions/IMeshBus.cs, src/agent/Mesh/Abstractions/ITaskQueue.cs, src/agent/Mesh/Abstractions/IMeshStateStore.cs, src/agent/Mesh/InProcess/
Dependencies
- блокирует / опирается на: task_003 — hybrid-storage
- блокирует / опирается на: task_043 — mesh-router
Risks / Rollback
Утечка абстракций; минимальный набор методов, чёткие контракты, контрактные тесты на каждую реализацию.
Links
- Backlog: ../backlog.md
- Roadmap (EN): ../../ROADMAP-EN.md
- Roadmap (RU): ../../ROADMAP-RU.md