Notification Operational Architecture
Summary
A single .NET 8 process hosting one HTTP surface and one background consumer, with two runtime dependencies: PostgreSQL and RabbitMQ. The two behave very differently when unavailable.
Audience
DevOps engineers, engineers, support, architects and QA.
Service startup
Operational dependencies
| Dependency | Required for | Behavior when unavailable |
|---|---|---|
| PostgreSQL | Everything — all reads and writes | Startup fails at the migration step unless migrations are skipped |
| RabbitMQ | Event consumption only | Startup succeeds; the consumer retries indefinitely in the background |
| SMTP host | Email delivery, only when the SMTP provider is selected | Delivery attempts fail and retry; the service stays up |
This asymmetry is the single most important operational fact about the service. A database outage prevents the process from starting; a broker outage leaves a fully healthy-looking process that consumes nothing.
Service lifecycle
Start. Migration and seeding run synchronously before the host serves traffic, inside a temporary scope. The hosted consumer starts after the host is running and connects on its own schedule, so HTTP is available before consumption begins.
Steady state. One consumer holds one connection and one channel, with automatic recovery enabled and a fixed network recovery interval. Each delivery is processed in its own dependency-injection scope. HTTP requests are handled independently with their own scopes.
Broker reconnect. Connection failures are caught by an outer loop that logs a warning naming the host and port, waits a fixed interval and retries — indefinitely, with no attempt cap and no escalation.
Stop. The base stop completes first, then the channel and connection are disposed. Because the consumer passes its stopping token into dispatch, an in-flight event is cancelled mid-processing rather than drained, which given the many-small-saves persistence model can leave a partially processed event with no idempotency record.
Scaling posture
Nothing in the reviewed source prevents multiple instances. All instances would declare the same durable queue and compete for deliveries, which is a valid competing-consumer arrangement.
Two consequences follow from source: every instance applies migrations at startup, so a rollout produces concurrent migration attempts; and prefetch applies per consumer, so total in-flight work scales with instance count while ordering guarantees remain absent.
Deployment inputs
The service reads configuration from its content root, so it must be started from a directory containing its settings file — which is why the smoke script starts it from its build output directory.
A single environment variable, the migration skip flag, alters startup behavior. It also suppresses seeding.
Classification
Transitional.
Requires confirmation
Target instance count, orchestration probes, and whether migrations should move out of startup require confirmation.
Related Articles
See Also
Keywords
- Notification database
- Operational Architecture
- Draft database documentation
Source References
microservices/src/notification-service/Program.csmicroservices/src/notification-service/Messaging/NotificationEventConsumer.csmicroservices/src/notification-service/Application/NotificationOptions.csmicroservices/src/notification-service/Seed/DefaultTemplateSeeder.csmicroservices/src/notification-service/Properties/launchSettings.json
Revision Information
- Status: Draft
- Last reviewed: 2026-07-21
- Review cycle: Quarterly