Skip to content

feat: implement v2 interfaces across modules (v1.12.1)#195

Closed
intel352 wants to merge 67 commits intoCrisisTextLine:mainfrom
GoCodeAlone:feat/reimplementation
Closed

feat: implement v2 interfaces across modules (v1.12.1)#195
intel352 wants to merge 67 commits intoCrisisTextLine:mainfrom
GoCodeAlone:feat/reimplementation

Conversation

@intel352
Copy link

Summary

Implements the new v2 enhancement interfaces (MetricsProvider, Drainable, Reloadable) across all applicable modules, targeting modular core v1.12.1.

Module Enhancements

Module MetricsProvider Drainable Reloadable
database ✅ pool stats ✅ drain connections ✅ pool settings
cache ✅ item count ✅ TTL, max items
eventbus ✅ delivery stats ✅ drain queues
httpserver ✅ server state ✅ drain flag ✅ timeouts
scheduler ✅ job counts ✅ persist + drain
reverseproxy ✅ request stats ✅ stop health checker
eventlogger ✅ flush outputs

Other Changes

  • All 14 modules bumped to modular v1.12.1
  • 35 new tests across 7 modules, all passing
  • Includes prior v2 core enhancements (12 features) and CI fixes

Test plan

  • All 14 modules build cleanly (go build ./...)
  • All new v2 interface tests pass
  • Core tests pass (go test ./...)
  • Compile-time interface assertions in all enhanced modules

🤖 Generated with Claude Code

Copilot AI and others added 30 commits March 6, 2026 21:31
…ests

Co-authored-by: intel352 <77607+intel352@users.noreply.github.com>
Co-authored-by: intel352 <77607+intel352@users.noreply.github.com>
…ategies

Co-authored-by: intel352 <77607+intel352@users.noreply.github.com>
… fix MakeJSONResponse status format

Co-authored-by: intel352 <77607+intel352@users.noreply.github.com>
Reset GoCodeAlone/modular to CrisisTextLine/modular main (v1.11.11+16 commits).
Changed all module paths from CrisisTextLine to GoCodeAlone.
Merged CrisisTextLine#192 (composite route strategies).
Added reimplementation plans for previously GoCodeAlone-specific features:
- TenantGuard framework
- Dynamic Reload Manager
- Aggregate Health Service
- BDD/Contract Testing framework

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update all sub-modules to reference GoCodeAlone/modular v1.12.0.
Add replace directive for eventbus mocks resolution.
Fix letsencrypt httpserver dependency version.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The eventbus/v2 go.mod had a require + replace for the v1 eventbus
module path (for mocks). The replace directive doesn't propagate to
consumers, causing 'unknown revision' errors when downstream modules
run go mod tidy.

Fix: change test imports from .../eventbus/mocks to .../eventbus/v2/mocks
(the correct v2 import path) and remove the v1 require/replace.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Analyzed existing codebase against all 4 plans:
- TenantGuard: ~50% exists (context, service, config, decorators)
- Dynamic Reload: ~25% exists (observer, field tracking, config providers)
- Aggregate Health: ~15% exists (reverseproxy health checker)
- BDD/Contract Testing: ~65% exists (121 tests, contract CLI, CI)

Revised checklists to only cover remaining work.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… emission

Implements HealthProvider interface, HealthReport/AggregatedHealth types,
provider adapters (simple, static, composite), and AggregateHealthService
with fan-out evaluation, panic recovery, cache TTL, temporary error
detection, and CloudEvent emission on status changes. 17 tests including
concurrency and race-detector verified.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduces TenantGuard interface and StandardTenantGuard implementation
with strict/lenient/disabled modes, whitelist support, ring buffer
violation tracking, and CloudEvents emission on violations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…and rollback

Add Reloadable interface to module.go for modules that support runtime
config reloading. Implement ReloadOrchestrator with single-flight
execution, exponential backoff circuit breaker, reverse-order rollback
on partial failure, and CloudEvents emission for reload lifecycle.

New files:
- reload.go: ChangeType, ConfigChange, FieldChange, ConfigDiff, ReloadTrigger types
- reload_orchestrator.go: ReloadOrchestrator with queue, circuit breaker, rollback
- reload_test.go: comprehensive tests (ConfigDiff, orchestrator, rollback, circuit breaker, concurrency)

Also fix pre-existing WithLogger name collision in health_service.go -> WithHealthLogger.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace dynamic errors.New() with sentinel errors (err113)
- Add StatusUnknown case to exhaustive switch (exhaustive)
- Derive request context from parent context (contextcheck)
- Wrap interface method error return (wrapcheck)
- Fix gofmt alignment in builder.go, contract_verifier.go, observer.go
- Update letsencrypt go.sum for httpserver@v1.12.0 checksum

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reload orchestrator:
- Sort targets by module name for deterministic reload/rollback order
- Make Stop() idempotent with sync.Once, reject requests after stop
- Move noop check before started event to avoid misleading event stream
- Apply default 30s timeout when ReloadTimeout() returns <= 0
- Add doc comment noting application integration is a follow-up

Health service:
- Switch from *log.Logger to modular.Logger for consistent structured logging
- Return deep copies from Check() to prevent cache mutation by callers
- Use NewCloudEvent helper for proper event ID/specversion
- Prefer StatusUnhealthy over StatusUnknown on tie-breaks

Tenant guard:
- Switch from *log.Logger to modular.Logger for consistent structured logging
- Deep-copy whitelist in constructor, convert to set for O(1) lookups
- Use NewCloudEvent helper for proper event ID/specversion
- Use structured logging (Warn with key-value pairs) instead of Printf
- Wire guard into application service registry via builder

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add ErrReloadStopped for stopped orchestrator (distinct from channel full)
- Guard against nil logger with nopLogger fallback in NewReloadOrchestrator
- Fix BenchmarkReload to call processReload directly instead of queue+drain
- Update rollback test to assert deterministic sorted order

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- reload_orchestrator: add recover guard in RequestReload to prevent
  panic on send-to-closed-channel race with Stop()
- builder: use app.RegisterService() instead of direct SvcRegistry map
  mutation for tenant guard registration
- reload_contract_bdd_test: make rollback assertion deterministic now
  that targets are sorted by name

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- reload_orchestrator: extract handleReload() to properly scope context
  lifetime (no defer cancel leak in loop), propagate req.Ctx values and
  cancellation to module Reload calls instead of only copying deadline
- health_service: worstStatus now maps StatusUnknown → StatusUnhealthy
  in output, consistent with documented aggregation behavior
- reload_test: replace all time.Sleep waits with polling waitFor helper
  for deterministic CI-safe synchronization
- reload_contract_bdd_test: replace time.Sleep waits with event/call
  polling helpers (bddWaitForEvent, bddWaitForCalls)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Keep context chain rooted in parentCtx and apply request deadline via
context.WithDeadline instead of swapping the base context.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- contract_verifier: guard checkReloadIdempotent with goroutine+select
  so a misbehaving module cannot block the verifier indefinitely
- health_service: Check now selects on ctx.Done() when collecting
  provider results, returning ctx.Err() on cancellation/timeout
- tenant_guard: log NotifyObservers errors instead of silently dropping;
  update TenantGuardLenient doc to clarify logging is best-effort
- reload_contract_bdd_test: simulate elapsed backoff by backdating
  lastFailure instead of manually clearing circuit breaker state
- reload_orchestrator: propagate req.Ctx cancellation via background
  goroutine watching req.Ctx.Done(), not just deadline

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add ErrReloadTimeout sentinel error, use in contract verifier
- Wrap ctx.Err() in health_service.Check for wrapcheck compliance

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: revise reimplementation plans with gap analysis

Analyzed existing codebase against all 4 plans:
- TenantGuard: ~50% exists (context, service, config, decorators)
- Dynamic Reload: ~25% exists (observer, field tracking, config providers)
- Aggregate Health: ~15% exists (reverseproxy health checker)
- BDD/Contract Testing: ~65% exists (121 tests, contract CLI, CI)

Revised checklists to only cover remaining work.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add aggregate health service with providers, caching, and event emission

Implements HealthProvider interface, HealthReport/AggregatedHealth types,
provider adapters (simple, static, composite), and AggregateHealthService
with fan-out evaluation, panic recovery, cache TTL, temporary error
detection, and CloudEvent emission on status changes. 17 tests including
concurrency and race-detector verified.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add TenantGuard enforcement layer for multi-tenant isolation

Introduces TenantGuard interface and StandardTenantGuard implementation
with strict/lenient/disabled modes, whitelist support, ring buffer
violation tracking, and CloudEvents emission on violations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add dynamic reload manager with orchestrator, circuit breaker, and rollback

Add Reloadable interface to module.go for modules that support runtime
config reloading. Implement ReloadOrchestrator with single-flight
execution, exponential backoff circuit breaker, reverse-order rollback
on partial failure, and CloudEvents emission for reload lifecycle.

New files:
- reload.go: ChangeType, ConfigChange, FieldChange, ConfigDiff, ReloadTrigger types
- reload_orchestrator.go: ReloadOrchestrator with queue, circuit breaker, rollback
- reload_test.go: comprehensive tests (ConfigDiff, orchestrator, rollback, circuit breaker, concurrency)

Also fix pre-existing WithLogger name collision in health_service.go -> WithHealthLogger.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add contract verifier and performance benchmarks

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add BDD contract tests for reload and health subsystems

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: resolve CI lint failures and letsencrypt checksum mismatch

- Replace dynamic errors.New() with sentinel errors (err113)
- Add StatusUnknown case to exhaustive switch (exhaustive)
- Derive request context from parent context (contextcheck)
- Wrap interface method error return (wrapcheck)
- Fix gofmt alignment in builder.go, contract_verifier.go, observer.go
- Update letsencrypt go.sum for httpserver@v1.12.0 checksum

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: address all PR review comments

Reload orchestrator:
- Sort targets by module name for deterministic reload/rollback order
- Make Stop() idempotent with sync.Once, reject requests after stop
- Move noop check before started event to avoid misleading event stream
- Apply default 30s timeout when ReloadTimeout() returns <= 0
- Add doc comment noting application integration is a follow-up

Health service:
- Switch from *log.Logger to modular.Logger for consistent structured logging
- Return deep copies from Check() to prevent cache mutation by callers
- Use NewCloudEvent helper for proper event ID/specversion
- Prefer StatusUnhealthy over StatusUnknown on tie-breaks

Tenant guard:
- Switch from *log.Logger to modular.Logger for consistent structured logging
- Deep-copy whitelist in constructor, convert to set for O(1) lookups
- Use NewCloudEvent helper for proper event ID/specversion
- Use structured logging (Warn with key-value pairs) instead of Printf
- Wire guard into application service registry via builder

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: address second round of PR review comments

- Add ErrReloadStopped for stopped orchestrator (distinct from channel full)
- Guard against nil logger with nopLogger fallback in NewReloadOrchestrator
- Fix BenchmarkReload to call processReload directly instead of queue+drain
- Update rollback test to assert deterministic sorted order

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: address remaining PR review comments (round 3)

- reload_orchestrator: add recover guard in RequestReload to prevent
  panic on send-to-closed-channel race with Stop()
- builder: use app.RegisterService() instead of direct SvcRegistry map
  mutation for tenant guard registration
- reload_contract_bdd_test: make rollback assertion deterministic now
  that targets are sorted by name

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: address round 4 PR review comments

- reload_orchestrator: extract handleReload() to properly scope context
  lifetime (no defer cancel leak in loop), propagate req.Ctx values and
  cancellation to module Reload calls instead of only copying deadline
- health_service: worstStatus now maps StatusUnknown → StatusUnhealthy
  in output, consistent with documented aggregation behavior
- reload_test: replace all time.Sleep waits with polling waitFor helper
  for deterministic CI-safe synchronization
- reload_contract_bdd_test: replace time.Sleep waits with event/call
  polling helpers (bddWaitForEvent, bddWaitForCalls)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: resolve contextcheck lint error in handleReload

Keep context chain rooted in parentCtx and apply request deadline via
context.WithDeadline instead of swapping the base context.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: address round 5 PR review comments

- contract_verifier: guard checkReloadIdempotent with goroutine+select
  so a misbehaving module cannot block the verifier indefinitely
- health_service: Check now selects on ctx.Done() when collecting
  provider results, returning ctx.Err() on cancellation/timeout
- tenant_guard: log NotifyObservers errors instead of silently dropping;
  update TenantGuardLenient doc to clarify logging is best-effort
- reload_contract_bdd_test: simulate elapsed backoff by backdating
  lastFailure instead of manually clearing circuit breaker state
- reload_orchestrator: propagate req.Ctx cancellation via background
  goroutine watching req.Ctx.Done(), not just deadline

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: resolve err113 and wrapcheck lint errors

- Add ErrReloadTimeout sentinel error, use in contract verifier
- Wrap ctx.Err() in health_service.Check for wrapcheck compliance

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Covers 12 gaps identified in framework audit: config-driven deps,
drainable shutdown, phase tracking, parallel init, type-safe services,
service readiness events, plugin interface, reload integration,
config file watcher, secret resolution, slog adapter, metrics hooks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
12 tasks covering all audit gaps: config-driven deps, drainable
shutdown, phase tracking, parallel init, type-safe services,
service readiness, plugin interface, reload integration,
secret resolver, config watcher, slog adapter, metrics hooks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…hints

Allow injecting dependency edges into the module dependency graph from
the builder/config level, without requiring modules to implement the
DependencyAware interface. Hints are merged into the graph before
topological sort, enabling correct init ordering and cycle detection.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
intel352 and others added 27 commits March 9, 2026 23:58
Applied gopls modernization across 63 files:
- Replace interface{} with any (Go 1.18+)
- Replace reflect.TypeOf((*T)(nil)).Elem() with reflect.TypeFor[T]() (Go 1.22+)
- Replace reflect.Ptr with reflect.Pointer
- Replace manual loops with slices.Contains and maps.Copy
- Replace C-style for loops with range N syntax (Go 1.22+)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove discarded error vars assigned to _ in logger_decorator_base_bdd_test.go
- Fix indentation in config_field_tracking_test.go switch case
- Fix orphaned indentation from slices.Contains refactoring in observer_test.go and tenant_service.go
- Restore tagValidate and tagDesc constants in config_validation.go
- Propagate fsnotify.Watcher.Close() error in configwatcher Stop method
- Benchmark GetService through registry lock instead of pre-copied map
- Add performance note to GetTypedService doc comment

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…laceholders (#82)

* Initial plan

* chore: initial plan to replace realistic-looking examples with generic values

Co-authored-by: intel352 <77607+intel352@users.noreply.github.com>

* fix: replace realistic-looking connection strings and credentials with generic alternatives

Replace chimera_app → myapp_user, chimera_backend → myappdb,
real-looking RDS cluster hostname with generic alternatives,
and MySecretPassword123 with MySecretP@ssword.

Update 'Your Specific Use Case' section to generic 'Example Use Case'.

Co-authored-by: intel352 <77607+intel352@users.noreply.github.com>

* Replace realistic-looking DB credentials and hostnames with generic placeholders

Co-authored-by: intel352 <77607+intel352@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: intel352 <77607+intel352@users.noreply.github.com>
Keep HEAD (ours) for all modernization changes (range N, wg.Go, slices.Contains,
maps.Copy, any, t.Context, TypeFor) and v2 enhancements (builder fields, plugin
support, drain timeout, parallel init, dynamic reload, phase events). Incorporate
new helper methods from main (reset(), getLastChanges(), getEvents()).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add RegisterServiceForModule() to EnhancedServiceRegistry that takes
the module directly instead of relying on the shared currentModule
field. initModule() now uses this method, making parallel init safe
from the SetCurrentModule/ClearCurrentModule race where concurrent
goroutines could associate services with the wrong module.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
All CI workflows now use Go ^1.26 to match go.mod requirements.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…iles

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- reverseproxy: replace deprecated proxy.Director (SA1019) with proxy.Rewrite
  using httputil.ProxyRequest API, including all proxy copy sites
- scheduler: add G118 nolint for context.WithCancel where cancel is stored
  in struct field and called in Stop()
- eventbus: add G118 nolint for context.WithCancel in memory, nats, redis
  Start() methods where cancel is stored and called in Stop()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix gofmt formatting in application.go, config_field_tracking.go, health_service.go
- Wrap external errors in configwatcher (fsnotify), secret_resolver, service_typed
- Check errcheck on stopWatching() call in configwatcher

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…l.go

Go 1.26's stricter vet treats Debug(msg string, args ...any) interface methods
as printf-like, flagging structured logging calls. Added debugLog helper that
formats key-value pairs into the message string and routes through a func(string)
wrapper to avoid the vet's printf detection.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix gofmt alignment in feeders/yaml.go, phase.go, tenant_service.go
- Change //nolint:G118 to //nolint:gosec (golangci-lint uses linter names)
- Add G118 suppression for durable_memory.go and kafka.go
- Fix contextcheck nolint in scheduler.go
- Suppress SA1019 on proxy.Director = nil (required when using Rewrite)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… guard

- Restructure registerServiceLocked to isolate the critical section in
  registerServiceInner, ensuring the lock is always released even on panic
- GetServicesByModule now returns a copy of the internal slice for thread safety
- computeDepthLevels breaks out of the loop when no progress is made instead
  of spinning indefinitely on unresolvable dependencies
- configwatcher uses clear(changedPaths) instead of reassigning the map variable
  in the AfterFunc closure

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…rallel init

computeDepthLevels previously only considered DependencyAware.Dependencies()
and dependencyHints, missing implicit service-based dependencies resolved by
resolveDependencies. Now resolveDependencies returns the complete graph and
computeDepthLevels uses it directly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ompatibility

Go 1.26 enforces that ReverseProxy has exactly one of Director or Rewrite
set. Proxy copies in createBackendProxyHandler were only copying Rewrite,
causing failures when the source proxy used Director (e.g. from
NewSingleHostReverseProxy). Now copies preserve both fields. Also switched
createReverseProxyForBackend to use bare &httputil.ReverseProxy{} with
Rewrite instead of NewSingleHostReverseProxy + Director=nil.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…and differ

- Examples (verbose-debug, instance-aware-db): migrate database import
  from v1 to v2 path, fix go.mod require/replace directives
- examples-ci.yml: fix grep pattern to match `../..` without trailing slash
- configwatcher: add go.mod/go.sum for standalone module CI
- contract-check.yml: use commit SHA instead of branch name for PR checkout
- contract differ: normalize `interface{}` and `any` as equivalent types
  to prevent false breaking-change reports during Go modernization

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…events

- application.go: fix moduleRegistry race in initModule log line (use local var)
- application.go: guard CollectAllMetrics with initMu snapshot
- application.go: emit EventTypeAppPhaseChanged via phaseChangeHook in
  ObservableApplication
- application.go: add PhaseAware, ReloadableApp, MetricsCollector optional
  interfaces so callers don't need type assertions to *StdApplication
- service.go: restructure locking — registerAndNotify acquires/releases lock
  with defer-safe pattern, removing fragile caller-must-hold contract
- configwatcher: log watcher errors instead of silently discarding them
- configwatcher: check stopCh in AfterFunc callback to avoid firing onChange
  after shutdown
- configwatcher: add WithLogger option, capture app logger in Init
- configwatcher_test: check os.WriteFile errors

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- builder.go: unwrap ApplicationDecorator chain to find the underlying
  StdApplication/ObservableApplication before propagating options
  (dependencyHints, drainTimeout, dynamicReload, parallelInit)
- application.go: validate that both From and To modules in dependency
  hints exist in moduleRegistry before merging into the graph

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds v2 enhancement interfaces to the eventbus module:
- MetricsProvider: exposes delivery stats (delivered, dropped, topics, subscribers)
- Drainable: PreStop signals drain phase before shutdown

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds v2 enhancement interfaces to the cache module:
- MetricsProvider: exposes item count, max items, connected status
- Reloadable: hot-reload TTL, max items, cleanup interval

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds v2 enhancement interfaces to the scheduler module:
- MetricsProvider: exposes job counts, worker count, running state
- Drainable: PreStop persists jobs and signals drain before shutdown

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…interfaces

Adds v2 enhancement interfaces to the database module:
- MetricsProvider: exposes sql.DBStats (connections, pool utilization)
- Drainable: PreStop drains active connections before shutdown
- Reloadable: hot-reload pool settings without reconnecting

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds v2 enhancement interfaces to the reverseproxy module:
- MetricsProvider: exposes request counts, error counts, backend count
- Drainable: PreStop stops health checker during drain phase

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds v2 enhancement interfaces to the httpserver module:
- Drainable: PreStop signals drain phase before graceful shutdown
- Reloadable: hot-reload server timeouts without restart
- MetricsProvider: exposes server state (started, port)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 11, 2026 11:14
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

@intel352 intel352 closed this Mar 11, 2026
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.

3 participants