Add WolverineHeartbeat emission (CritterWatch#72)#2688
Merged
jeremydmiller merged 1 commit intomainfrom May 7, 2026
Merged
Conversation
Periodic node liveness signal emitted via the normal publish pipeline. Operators opt in with `opts.EnableHeartbeats(...)` and route heartbeats to their monitoring stack (e.g. CritterWatch) with a publish rule. - HeartbeatPolicy on WolverineOptions.Heartbeat (Enabled, Interval) - WolverineHeartbeat record (ServiceName, NodeNumber, SentAt, Uptime) - HeartbeatBackgroundService publishes on each interval tick - EnableHeartbeats(TimeSpan?) extension wires the hosted service The consumption side (tracking + alerting on missing heartbeats) lives in CritterWatch and is intentionally out of scope here. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Ships the emit side of node-level heartbeats so external monitors (e.g. CritterWatch) can detect when a Wolverine node has gone dark. Operators opt in with one line and route heartbeats wherever they want via the normal publish pipeline.
What shipped
HeartbeatPolicyonWolverineOptions.Heartbeat—Enabled(defaulttrue) andInterval(default30s).WolverineHeartbeatrecord —ServiceName,NodeNumber,SentAt,Uptime.HeartbeatBackgroundService—BackgroundServicethat publishes on each interval tick usingnew MessageBus(runtime).PublishAsync(...). Bails out early whenEnabled == false. Swallows-and-logs publish exceptions so a transport hiccup never crashes the host.EnableHeartbeats(TimeSpan?)extension — wires the singleton + hosted service registration; supplied interval (when given) overrides the policy.docs/guide/runtime/heartbeats.mdwith a quickstart, field reference, and configuration notes; linked from the General nav.What's out of scope
The consumption side — tracking received heartbeats per node, alerting on missing ones, and visualizing health — is intentionally CritterWatch's job and lives in that repo (CritterWatch#72).
Test coverage
Added
src/Testing/CoreTests/Runtime/Heartbeat/HeartbeatBackgroundServiceTests.cswith five tests covering:ServiceNameandNodeNumberfromWolverineOptions/Durability.HeartbeatPolicy.Enabled == false.EnableHeartbeatssets the policy and registers the hosted service inWolverineOptions.Services.EnableHeartbeats()without an interval preserves the default 30-second cadence.dotnet test src/Testing/CoreTests/CoreTests.csprojis green on net8.0, net9.0, and net10.0 (1538 / 1542 / 1542 tests, 0 failures).Companion work
This pairs with CW#73 (active-pull node health checks) and CW#70 (transport health probes) for a coherent monitoring story: heartbeats are the cheap passive signal, the other two cover "alive but degraded" cases.
Test plan
dotnet build src/Wolverine/Wolverine.csproj— clean.dotnet test src/Testing/CoreTests/CoreTests.csproj— passing on all three target frameworks.MessageBusapproach and the placement ofEnableHeartbeats(chose top-levelWolverineOptionsExtensions.csto match the plan; happy to relocate next to the heartbeat folder if preferred).🤖 Generated with Claude Code