Skip to content

feat: implement settings change subscriptions for service hot-reload #503

@Aureliolo

Description

@Aureliolo

Summary

Implement a generic mechanism for services to subscribe to #settings message bus channel and react to runtime setting changes by rebuilding affected service instances (ProviderRegistry, ModelResolver, MemoryBackend, etc.).

Context

SettingsService already publishes change notifications to the #settings message bus channel when settings are written or deleted (see service.py:_publish_change()). However, no services currently subscribe to these notifications. Startup-time consumers build service instances once from config and never update:

  • ProviderRegistry.from_config(root_config.providers) — builds driver instances
  • ModelResolver.from_config(root_config.providers) — builds model index
  • ModelRouter(routing_config, providers) — builds routing strategy
  • create_memory_backend(config.memory) — builds memory backend

When a setting changes at runtime (e.g., provider API key rotated via the settings API), these services continue using stale config until restart.

Scope

  • Create a SettingsSubscriber protocol or base class that services implement
  • Implement a listener on the #settings message bus channel that dispatches to registered subscribers
  • Each subscriber declares which (namespace, key) pairs it cares about
  • On change: subscriber rebuilds the affected service and swaps it into AppState
  • Thread-safe service swap (atomic reference replacement)
  • Graceful handling of rebuild failures (log error, keep old instance)

Design Considerations

  • Memory backend has restart_required=True — change notification should flag this to the operator rather than attempting hot-reload
  • Provider services could be rebuilt without restart
  • Coordination settings take effect per-request already (via ConfigResolver composed reads from feat: migrate existing config paths to read through SettingsService #497), so no subscriber needed there

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    prio:mediumShould do, but not blockingscope:large3+ days of workspec:architectureDESIGN_SPEC Section 15 - Technical Architecturespec:providersDESIGN_SPEC Section 9 - Model Provider Layertype:featureNew feature implementation

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions