Handle a degraded construction¶
Both return values can be meaningful at once. The bus is complete and correct for everything that was applied; the error is the complete list of what was not.
The conservative path costs you nothing¶
This is correct and is what most services should do. The degraded path is available only to callers who look for it, so nothing is made worse for anybody by its existing.
The degraded path¶
bus, err := messaging.New(backend, settings)
if bus == nil {
return err // fatal: nothing usable was built
}
if err != nil {
log.Warn("messaging started with settings the backend could not apply", "detail", err)
}
The test is bus == nil, not err != nil. A nil bus means a fatal problem; a non-nil bus with an
error means it is running with less than you asked for.
What degrades, and what is fatal¶
The line is ownership, not severity.
| Setting | Class |
|---|---|
| An overflow policy the backend does not offer | degraded |
| A wildcard pattern on a backend with no pattern support | fatal |
| A delivery mode the backend does not declare | fatal |
AtLeastOnce on a backend that does not survive a restart, without AllowVolatile |
fatal |
ExtendLease on a backend that cannot extend a lease |
fatal |
StartAt: AllAvailable on a backend declaring no replay |
fatal |
| A subscription that cannot be bounded | fatal |
| Discards that cannot be counted or attributed | fatal |
| An invalid subject pattern | fatal |
| A competing subscription with no group | fatal |
| Two subscriptions with the same name | fatal |
| No backend at all | fatal |
| No subscription declared at all | fatal |
Overflow is the one setting that degrades; every other capability mismatch above is fatal, because a delivery guarantee, a pattern language or a lease is a promise this module makes to a handler's author, and downgrading one silently changes what that handler is entitled to assume without telling them. A backend declining an overflow policy changes only what happens at a full queue, which is visible and countable either way. See what happens at a full queue.
Two properties worth relying on¶
A degraded setting is not applied at all — not substituted, clamped or approximated. Asking for
ShedOldest on a backend that cannot do it gets that backend's native behaviour, because delivering
a value nobody requested while reporting success for that field is worse than saying plainly that it
was dropped.
The error names every problem, not the first. Three unsupported settings produce one error naming all three, rather than one round trip at a time.
An unreachable backend is not a construction failure¶
Construction does not connect, deliberately, so that a briefly unavailable cluster does not stop your
application booting. Unreachability shows up exactly once, where you are already looking:
Ready() does not close and your own timeout fires.