Skip to content

Commit e720a10

Browse files
endrju19Andrzej Kobyliński
andauthored
ADR: Channel size estimation is not supported (#257)
## Summary - Adds ADR documenting the decision to not expose `Channel.estimateSize()` or any size estimation on channels - The lock-free segment-based algorithm tracks send/receive **attempts** (not completions), so interrupted operations permanently inflate any naive `senders - receivers` estimate - Kotlin's kotlinx.coroutines (same algorithm) deliberately omits any size method for the same reason - Users who need channel-level metrics should build external solutions (e.g., wrapping send/receive with their own counters) Resolves #189. Supersedes #254. Co-authored-by: Andrzej Kobyliński <andrzej.kobylinski@extern.corify.de>
1 parent 84e145e commit e720a10

File tree

1 file changed

+34
-0
lines changed

1 file changed

+34
-0
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# 1. Channel Size Estimation Is Not Supported
2+
3+
Date: 2026-02-13
4+
5+
## Status
6+
7+
Accepted
8+
9+
## Context
10+
11+
A common monitoring/observability use case is knowing how many items are currently buffered in a channel. PR #254 proposed adding `Channel.estimateSize()` to support this.
12+
13+
Jox channels use a lock-free segment-based algorithm. The algorithm maintains two monotonically increasing atomic counters: `senders` and `receivers`. A naive size estimate would be `senders - receivers`, but these counters track **attempts**, not completions.
14+
15+
When a send is interrupted (e.g., channel is full, sender blocks, thread is interrupted), the `senders` counter stays permanently incremented — it is never decremented. This means N interrupted sends cause a permanent inflation of N in the estimate. This is not transient concurrency imprecision; it is a structural deficiency of using attempt counters for size estimation.
16+
17+
Fixing this properly would require adding completion counters (additional `volatile long` fields incremented on each successful send/receive), adding an overhead per operation to the hot path — the core performance-critical code that every send and receive must execute.
18+
19+
## Decision
20+
21+
Do not expose size estimation on channels.
22+
23+
Kotlin's kotlinx.coroutines — which uses the same algorithm — deliberately does not expose any size method on `Channel`. Their stance: channels are communication primitives, not inspectable containers. The lock-free segment design makes reliable size estimation fundamentally impractical without hot-path performance cost.
24+
25+
For monitoring, Kotlin relies on the coroutines debug agent (tracking coroutine lifecycle — suspended/running) rather than channel internals.
26+
27+
Users who need channel-level metrics should build external solutions (e.g., wrapping send/receive with their own counters, or application-level metrics).
28+
29+
## Consequences
30+
31+
- **No misleading API**: users won't rely on an estimate that silently drifts from reality after interruptions.
32+
- **No hot-path performance cost**: avoids adding atomic increments to every send/receive operation.
33+
- **No built-in channel monitoring**: users needing buffer-level metrics must implement them externally.
34+
- **Consistent with Kotlin's approach**: aligns with the kotlinx.coroutines design decision for the same algorithm.

0 commit comments

Comments
 (0)