Skip to content

feat(metrics): expose forkd_branches_in_flight + cap (follow-up to #177)#183

Merged
WaylandYang merged 1 commit into
mainfrom
feat/branches-in-flight-metric
May 28, 2026
Merged

feat(metrics): expose forkd_branches_in_flight + cap (follow-up to #177)#183
WaylandYang merged 1 commit into
mainfrom
feat/branches-in-flight-metric

Conversation

@WaylandYang
Copy link
Copy Markdown
Contributor

Follow-up to #179, fulfilling the metrics suggestion @cortsdine raised in #177:

While in there: it'd be worth surfacing the current in-flight count via `/metrics` (`forkd_branches_in_flight`) so operators can size the cap empirically.

Adding both the in-flight count and the configured cap, so a Grafana panel can render "5 / 16 in-flight" without external knowledge of `FORKD_BRANCH_CONCURRENCY`.

New gauges on `/metrics`

Gauge Value
`forkd_branches_in_flight` `branch_in_flight.lock().len()` — number of BRANCHes currently writing `memory.bin`
`forkd_branch_concurrency_cap` The value the `branch_sem` Semaphore was constructed with (defaults to `DEFAULT_BRANCH_CONCURRENCY = 4`, configurable via `--branch-concurrency` / `FORKD_BRANCH_CONCURRENCY` from #179)

`tokio::Semaphore` doesn't expose its initial permit count, so the cap is cached on `AppState` in a new `branch_concurrency_cap: usize` field that mirrors the value from `DaemonConfig::branch_concurrency`. Threading change touches only the constructor — the rest of `AppState` is unchanged.

Tests

  • `metrics_emits_prometheus_text` extended to assert both new gauges appear with the `test_state` default cap (`DEFAULT_BRANCH_CONCURRENCY`).
  • New `metrics_branches_in_flight_tracks_slot_acquisitions` — acquires two `BranchSlot`s, asserts `forkd_branches_in_flight 2`, drops both, asserts the gauge returns to `0`. This is the same Drop-recovery invariant @henliveira singled out in Praise: the BranchSlot RAII guard is a really clean pattern #178; now externally observable.

Local on the dev box:

```
$ cargo fmt --all -- --check # clean
$ cargo check --all-targets # ok (12.4s)
$ cargo test -p forkd-controller --lib metrics
test http::tests::metrics_emits_prometheus_text ... ok
test http::tests::metrics_branches_in_flight_tracks_slot_acquisitions ... ok
test result: ok. 2 passed; 0 failed
```

Out of scope

The CHANGELOG is left to the maintainer (per the project convention). No CLI flag added — the cap is already configurable from #179.

…ency_cap

Follow-up to #179 — surfaces the in-flight BRANCH count and the
configured cap on /metrics, so operators can size
FORKD_BRANCH_CONCURRENCY empirically against their real workload
(per @cortsdine's suggestion in #177).

New gauges:
- forkd_branches_in_flight   (Mutex<HashSet<String>>.len() of BRANCHes
                              currently writing memory.bin)
- forkd_branch_concurrency_cap  (the value the Semaphore was
                                 constructed with; not exposed by
                                 tokio::Semaphore, so cached on
                                 AppState in a new branch_concurrency_cap
                                 field that mirrors the value from
                                 DaemonConfig::branch_concurrency)

The pair lets a Grafana panel show "5 / 16 in-flight" without external
knowledge of the cap.

Tests:
- Existing metrics_emits_prometheus_text extended to assert both new
  gauges appear with the default cap value.
- New metrics_branches_in_flight_tracks_slot_acquisitions verifies the
  in-flight gauge moves with BranchSlot acquire/drop — the actual
  Drop-recovery semantics @henliveira praised in #178, now visible to
  operators.
@WaylandYang WaylandYang merged commit 1ff38d8 into main May 28, 2026
2 checks passed
@WaylandYang WaylandYang deleted the feat/branches-in-flight-metric branch May 28, 2026 17:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant