Skip to content

CritterWatch Integration: Agent Health, Source Generators, Causation Tracking, HTTP Descriptors#2393

Merged
jeremydmiller merged 11 commits intomainfrom
cw-changes
Mar 31, 2026
Merged

CritterWatch Integration: Agent Health, Source Generators, Causation Tracking, HTTP Descriptors#2393
jeremydmiller merged 11 commits intomainfrom
cw-changes

Conversation

@jeremydmiller
Copy link
Copy Markdown
Member

Summary

10 commits with comprehensive CritterWatch monitoring infrastructure:

Agent Health Monitoring

  • IAgent extends IHealthCheck with default healthy implementation
  • DurabilityAgent tracks success/exception counts per recovery cycle
  • EventSubscriptionAgent (Marten + Polecat): stall detection, auto-restart after 3 consecutive checks, configurable thresholds
  • Listener agents: check ListeningStatus for TooBusy/Latched
  • CritterWatchObserver: 60s health check timer + state snapshot timer
  • AgentHealthReport message type for health status batching

Source Generators (Cold Start Optimization)

  • Wolverine.SourceGeneration project with IIncrementalGenerator
  • Handler and message type discovery at compile time
  • IWolverineTypeLoader interface with PreGeneratedHandlerTypes O(1) dictionary
  • WolverineTypeManifestAttribute for assembly-level marking
  • Extension discovery via source generator
  • ExtensionLoader checks type loader before AssemblyFinder scanning
  • HandlerGraph.compileWithTypeLoader() path bypasses runtime scanning

Runtime Message Causation Tracking

  • WolverineOptions.EnableMessageCausationTracking flag
  • IWolverineObserver.MessageCausedBy() with default interface no-op
  • MessageHandler.RecordCauseAndEffect() with ConcurrentDictionary latching
  • Executor wires causation recording before FlushOutgoingMessages
  • Each unique (incoming, outgoing, handler) triple reported once

HTTP Capability Descriptors

  • ICapabilityDescriptor extensibility interface
  • HttpCapabilityDescriptor in Wolverine.HTTP (routes + options)
  • ServiceCapabilities.AdditionalCapabilities for framework contributions

Circuit Breaker Observer Hooks

  • CircuitBreakerTripped/CircuitBreakerReset on IWolverineObserver

Dead Letter Queue Recovery

  • EnableDeadLetterQueueRecovery() with custom queue name overload

Bug Fixes

Test plan

  • CoreTests: 1213/1214 pass (1 pre-existing flaky TCP test)
  • CritterWatch integration tests pass
  • Source generator smoke tests discover handlers/messages
  • Agent health tests: 8 EventSubscriptionAgent stall/restart tests
  • Causation tracking: 4 interface/method verification tests

🤖 Generated with Claude Code

jeremydmiller and others added 11 commits March 30, 2026 10:45
EventSubscriptionAgent stall detection with auto-restart, observer
health check timer with configurable interval and logging

- IAgent extends IHealthCheck with default healthy implementation
- DurabilityAgent tracks success/exception counts per cycle
- Listener agents check ListeningStatus (TooBusy=Degraded, Latched=Unhealthy)
- EventSubscriptionAgent: stall detection, 3-cycle auto-restart,
  configurable thresholds, OnRestarted callback
- CritterWatchObserver: 60s periodic health check loop (configurable),
  Info logging for non-healthy, Debug for healthy, restart callback wiring
- AgentHealthReport and SubscriptionOrProjectionRestarted messages

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…tor cold start optimization

- IWolverineTypeLoader interface for compile-time type discovery
- WolverineTypeManifestAttribute for assembly-level marking
- HandlerGraph.Compile split: typeLoader path vs runtime scanning
- WolverineRuntime checks DI and assembly attributes for loader
- HandlerChain.AttachTypesSynchronously uses O(1) loader lookup

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…oller is null

Return empty array instead of throwing when NodeController hasn't
been initialized (Solo/MediatorOnly modes or before agent startup).
Also hardened RequestAgentHealthReportHandler and observer health
check loop with null-safe calls.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…xtension discovery

Phase D:
- IWolverineTypeLoader.PreGeneratedHandlerTypes dictionary for O(1) lookup
- Source generator scans WolverineHandlers namespace for pre-gen types
- AttachTypesSynchronously uses dictionary before linear scan fallback

Phase E:
- Generator discovers IWolverineExtension implementors
- ExtensionLoader checks type loader before AssemblyFinder scanning
- TryFindTypeLoader from assembly attribute

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ageStoreDiscovered

- ICapabilityDescriptor interface for frameworks to contribute to ServiceCapabilities
- HttpCapabilityDescriptor in Wolverine.HTTP (routes, options)
- Periodic state snapshot timer in CritterWatchObserver (60s)
- MessageStoreDiscovered published on RuntimeIsFullyStarted
- StateSnapshotInterval configurable for testing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- WolverineOptions.EnableMessageCausationTracking flag
- IWolverineObserver.MessageCausedBy() with default interface no-op
- MessageHandler.RecordCauseAndEffect() with ConcurrentDictionary latching
- Executor wires causation recording before FlushOutgoingMessages
  in both InvokeInlineAsync and ExecuteAsync paths
- _runtime field added to Executor for options/observer access

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…or + string overloads for testing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.

Rabbit MQ Conventional Routing Simplification & Queue configuration

1 participant