Skip to content

Commit 9e9f324

Browse files
kixelatedclaude
andauthored
moq-relay: count connected sessions per auth root for billing (#1574)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent ee55bb5 commit 9e9f324

3 files changed

Lines changed: 355 additions & 43 deletions

File tree

doc/bin/relay/config.md

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,8 @@ tls.disable_verify = true
158158

159159
Per-node stats publishing. When enabled, the relay publishes a single
160160
`<prefix>/node/<node>` broadcast (or `<prefix>/node` when `node` is unset)
161-
carrying JSON snapshots of every broadcast it's currently serving.
161+
carrying JSON snapshots of the broadcasts it's currently serving and of the
162+
sessions currently connected to it.
162163

163164
```toml
164165
[stats]
@@ -178,21 +179,24 @@ interval = 1
178179
node = "sjc/1"
179180
```
180181

181-
Each stats broadcast carries four tracks, one per `(tier, role)` pair:
182+
Each stats broadcast carries four per-broadcast tracks, one per
183+
`(tier, role)` pair, plus two session tracks (one per tier):
182184

183185
| Track | What it covers |
184186
|-----------------------------|---------------------------------------------|
185187
| `publisher.json` | external (e.g. customer) egress |
186188
| `subscriber.json` | external ingress |
187189
| `internal/publisher.json` | internal (e.g. mTLS cluster peer) egress |
188190
| `internal/subscriber.json` | internal ingress |
191+
| `sessions.json` | external connected sessions, keyed by root |
192+
| `internal/sessions.json` | internal connected sessions, keyed by root |
189193

190-
Each frame is a JSON object mapping broadcast path to a cumulative
191-
counter snapshot. An entry surfaces on any tick where the broadcast is
192-
live (any open counter still exceeds its `*_closed` counterpart, so a
193-
subscription could begin at any moment) or its snapshot changed since the
194-
previous tick. Once every counter equals its `*_closed` counterpart no
195-
traffic can flow, so the entry is dropped:
194+
Each per-broadcast frame is a JSON object mapping broadcast path to a
195+
cumulative counter snapshot. An entry surfaces on any tick where the
196+
broadcast is live (any open counter still exceeds its `*_closed`
197+
counterpart, so a subscription could begin at any moment) or its snapshot
198+
changed since the previous tick. Once every counter equals its `*_closed`
199+
counterpart no traffic can flow, so the entry is dropped:
196200

197201
```json
198202
{
@@ -228,6 +232,22 @@ Field semantics:
228232
- `bytes` / `frames` / `groups`: cumulative payload counters from the
229233
session loops (both the `moq-lite` and IETF `moq-transport` paths).
230234

235+
The session tracks (`sessions.json`, `internal/sessions.json`) instead map
236+
each auth root to a `{ sessions, sessions_closed }` snapshot. `sessions`
237+
bumps when a session authenticated under that root connects and
238+
`sessions_closed` when it disconnects, so `sessions - sessions_closed` is
239+
the number of sessions currently connected under the root. This counts
240+
presence regardless of whether any data flows, so a client connected to
241+
e.g. `/acme` is billable even while idle. A root entry is emitted while live
242+
or on the tick it changed, then dropped once no session under it remains:
243+
244+
```json
245+
{
246+
"acme": { "sessions": 3, "sessions_closed": 1 },
247+
"globex": { "sessions": 1, "sessions_closed": 0 }
248+
}
249+
```
250+
231251
Tier, role, and node are implied by the track and broadcast paths, so
232252
they aren't repeated inside the frame. Counters are cumulative and
233253
strictly monotonic; a counter going *backwards* across successive

0 commit comments

Comments
 (0)