Skip to content

Add IBrokerHealthProbe + RabbitMQ implementation (CritterWatch#70)#2686

Merged
jeremydmiller merged 1 commit intomainfrom
feat/cw70-brokerhealth
May 7, 2026
Merged

Add IBrokerHealthProbe + RabbitMQ implementation (CritterWatch#70)#2686
jeremydmiller merged 1 commit intomainfrom
feat/cw70-brokerhealth

Conversation

@jeremydmiller
Copy link
Copy Markdown
Member

Summary

Introduces an opt-in IBrokerHealthProbe contract on ITransport so monitoring layers (CritterWatch in particular) can render broker connectivity at a glance without bouncing connections. Ships the contract plus a RabbitMQ implementation; other transports follow in separate PRs.

This pairs with CritterWatch#73's bus/listener health checks for a coherent broker-monitoring story: CritterWatch drives the existing per-listener WolverineTransportHealthCheck for fine-grained endpoint health, and IBrokerHealthProbe for connection-level rollup.

What ships

  • src/Wolverine/Transports/IBrokerHealthProbe.csIBrokerHealthProbe, BrokerHealthSnapshot record, BrokerHealthStatus enum (Unknown/Healthy/Degraded/Unhealthy). Class-level XML doc spells out the non-destructive contract: probes don't reconnect or bounce; if the connection is down they return Unhealthy rather than throw.
  • src/Transports/RabbitMQ/Wolverine.RabbitMQ/Internal/RabbitMqBrokerHealthProbe.cs — partial on RabbitMqTransport so the transport itself implements IBrokerHealthProbe. Inspects IConnection.IsOpen / CloseReason, tracks reconnect counts via the existing RecoverySucceededAsync event in ConnectionMonitor, and reads TLS cert expiry from ConnectionFactory.Ssl.CertPath when configured. Initial connect is recorded as a timestamp but does not bump the reconnect counter — only genuine recoveries do. A reconnect within the last two minutes flips status from Healthy to Degraded.
  • src/Testing/CoreTests/Transports/IBrokerHealthProbe_contract_tests.cs — sanity-checks the public surface (enum members, record value-equality, custom probe implementation).
  • src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/RabbitMqBrokerHealthProbe_tests.cs — boots a Wolverine host with UseRabbitMq().AutoProvision(), asserts the transport is discoverable via runtime.Options.Transports.OfType<IBrokerHealthProbe>(), probes for Healthy, then closes both connections externally and probes again for Unhealthy.
  • docs/guide/messaging/transports/broker-health-probes.md — new docs page describing the contract, discovery pattern, status semantics, and per-transport support; linked from the RabbitMQ index page.

Deliberate scope cut

Azure Service Bus, Amazon SQS/SNS, Kafka, and Pulsar are not in this PR. They'll pattern-match the RabbitMQ implementation as their underlying client SDKs are surveyed; doing them all here would bloat the diff without changing the shape of the contract. The docs page lists them as Pending.

Test coverage

  • Contract tests: dotnet test src/Testing/CoreTests/CoreTests.csproj --filter IBrokerHealthProbe_contract_tests — 3 tests passing on net9.0.
  • RabbitMQ integration tests: dotnet test src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests --filter RabbitMqBrokerHealthProbe_tests — 3 tests passing locally on net9.0 against rabbitmq:4-management. Marked [Trait("Category", "Flaky")] to follow the project convention for tests that hit the broker.

Test plan

  • dotnet build against Wolverine, Wolverine.RabbitMQ, Wolverine.RabbitMQ.Tests, CoreTests — 0 errors.
  • Contract tests pass without Docker.
  • Integration tests pass with Docker + RabbitMQ container running.
  • CI runs the integration test on the standard RabbitMQ matrix.

🤖 Generated with Claude Code

Introduces a non-destructive, broker-level health probe contract that
monitoring layers (e.g. CritterWatch) can use to render transport
connectivity without bouncing connections. RabbitMqTransport implements
the contract directly, exposing IsOpen state, recent reconnects, and TLS
certificate expiry. Other broker transports (ASB / SQS / Kafka / Pulsar)
are deliberate follow-ups -- this PR is RabbitMQ-only by design.
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