ADR-005: CQS Static Queue Configuration and Push Model Deprecation¶
Status: Accepted Date: 2026-05
Context¶
The service currently supports two configuration entry points and two delivery models:
Configuration entry points
1. Static config (application.yml queues: map) — set at deploy time by platform operators.
2. Dynamic config (CreateOrConfigureQueue gRPC API) — set at runtime by consumer services themselves on startup.
Delivery models
1. Push — the changequeue-service POSTs notifications to consumer endpoints (same interface as PubSub push). Endpoint URL and concurrency are set via the Admin gRPC API.
2. Pull — consumer services long-poll via BatchDequeue / BatchAcknowledge gRPC.
The goal is for every consumer service to own its own queue provisioning. Static config and push delivery are operational overhead that will become unnecessary as services migrate to the self-service gRPC API.
Decision¶
We accept static config and push as a transitional state, not a permanent architecture. The migration plan is:
Phase 1 — Seed and freeze (done)
On first startup with an empty dynamic registry, the service seeds registry.json from application.yml once and never reads application.yml queue entries again. From that point on, the dynamic registry is the sole source of truth for which queues exist (ADR-004). Static config entries in application.yml become inert after the seed run and should be removed as each consumer migrates.
Phase 2 — Consumer migration (in progress)
Each consumer service adds a CreateOrConfigureQueue call to its own startup sequence. Once a service has made this call in all environments, its static entry in application.yml is deleted and its push config (if any) is removed from the Admin API.
Phase 3 — Remove static config support
When no entries remain in application.yml's queues: map, remove:
- The static config loading path in ChangeQueueRegistry.init().
- The seed-once branch (the empty-registry check becomes unreachable).
- The queues section from ChangeQueueConfig and the config schema.
Phase 4 — Remove push model
When all consumers have migrated to pull (gRPC BatchDequeue), remove:
- The push module (worker threads, push callout client, push config).
- Push-related entries from the Admin gRPC API.
- Push egress configuration from all application.yml and kustomize overlays.
Consequences¶
- Easier: Consumer services gain autonomy over their own queue configuration. Platform operators no longer need to coordinate deploy-time config changes when a new consumer comes online.
- Cleaner: The codebase converges toward a single configuration path (dynamic gRPC API) and a single delivery model (pull), reducing operational surface area.
- Migration risk: Until a consumer completes its migration, its queue config lives in
registry.jsonon GCS. If the file is lost and no static config fallback exists, the queue will not be recreated until the consumer callsCreateOrConfigureQueueagain (which happens on consumer startup). This is acceptable because the service is already stateless by design and queue contents are separately backed up. - Tracking: Each consumer's migration should be tracked as an explicit task. Removing a static entry before the consumer is updated will silently orphan its queue.