Skip to content

System.Threading.Channels

System.Threading.Channels flow

ChokaQ uses System.Threading.Channels as an in-process coordination primitive. Channels are not the durable queue. They are local buffers used to connect producer loops and consumer loops without blocking the whole worker.

Where Channels Appear

AreaChannel role
SQL workerLocal bounded prefetch buffer between SQL fetch and execution.
In-memory queuePrimary local queue for development and tests.

In SQL Server mode, SQL remains the durable source of truth. In in-memory mode, the channel is the queue and jobs are lost when the process exits.

Why Channels Fit

Channels provide:

  • async producer/consumer flow;
  • bounded capacity;
  • backpressure via BoundedChannelFullMode.Wait;
  • low allocation overhead compared with ad hoc locks;
  • clean shutdown through writer completion and cancellation.

Correctness Boundary

Channels do not provide durability, distributed coordination, or cross-process visibility. ChokaQ only relies on channels for local buffering. Durable state comes from SQL rows and SQL transitions.

Architecture Decision

Why this pattern?

Channels are a standard .NET primitive for async producer/consumer pipelines. They keep local worker code simple while avoiding custom queue implementations.

Trade-offs

Channels are process-local. Anything placed only in a channel disappears when the process exits. That is acceptable for SQL prefetch because SQL owns the source row and recovery can reset stale fetched rows. It is not acceptable as a production durable queue by itself.

Alternatives considered

AlternativeBenefitCost
BlockingCollectionFamiliar.Older blocking model, weaker async ergonomics.
Custom lock queueFull control.Easy to get cancellation/backpressure wrong.
External brokerDurable and scalable.Extra infrastructure and different product scope.

Additional Questions

Are channels the queue?
Only in in-memory mode. In SQL Server mode, channels are local buffers.

Why bounded channels?
Because unbounded local buffering hides pressure and risks memory exhaustion.

What happens on shutdown?
The writer completes, processors drain/release work, and SQL recovery handles stale fetched rows if the process exits before clean release.

Apache 2.0 Licensed