Give the forge's merges a durable consumer of their own: no max-deliver, no reset, a growing delay while held (issue 973)
This commit is contained in:
@@ -233,6 +233,18 @@ const ProvAppliedStream = "PROV_APPLIED"
|
||||
// all (ProvisionerAppliedSubject).
|
||||
const ProvAppliedSubjects = "prov.applied.>"
|
||||
|
||||
// eventsTheControllerFollows are the events the controller's events consumer takes: all it follows but the forge's
|
||||
// merges, which the merges consumer takes (MergesConsumerName).
|
||||
func eventsTheControllerFollows() []string {
|
||||
var out []string
|
||||
for _, subject := range ControllerFollows {
|
||||
if subject != ControllerFollows[3] {
|
||||
out = append(out, subject)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// DeliverSubjectFor is where a push consumer's messages land.
|
||||
//
|
||||
// **Per consumer, which means per stream as well as per name** (novox/hq 04-ISSUES/146). A push
|
||||
@@ -248,6 +260,9 @@ const ProvAppliedSubjects = "prov.applied.>"
|
||||
// durable's name to its stream, and this subject was the one place that scoping was dropped. It
|
||||
// stays inside what a controller may already subscribe (`_DELIVER.controller.>`).
|
||||
func DeliverSubjectFor(c Consumer) string {
|
||||
if c.DeliverSubject != "" {
|
||||
return c.DeliverSubject
|
||||
}
|
||||
return "_DELIVER." + c.Name + "." + c.Stream
|
||||
}
|
||||
|
||||
@@ -317,6 +332,13 @@ func Overlaps() []string {
|
||||
// ack subject is derived from (nats.go: `$JS.ACK.<stream>.controller.>`).
|
||||
const ControllerName = "controller"
|
||||
|
||||
// MergesConsumerName is the controller's durable consumer of the forge's merged event on EVENTS, apart from the
|
||||
// events consumer (novox/hq ADR 0407 decision 3, issue 973). A merge is never dropped, so this consumer has no
|
||||
// max-deliver, which would send a merge held five times to DEAD_LETTERS to wait for a person, and no healer
|
||||
// resets it, which would drop the merges it holds. A consumer of its own because both of those are properties of
|
||||
// a consumer, not of a subject.
|
||||
const MergesConsumerName = "controller-merges"
|
||||
|
||||
// ControllerSeat is the role the control plane holds, and ControllerStates are the facts it states
|
||||
// under it (novox/hq ADR 0134).
|
||||
//
|
||||
@@ -453,7 +475,7 @@ func MeshConsumers() []Consumer {
|
||||
{
|
||||
Name: ControllerName,
|
||||
Stream: "EVENTS",
|
||||
Filters: append(append([]string(nil), ControllerFollows...), AgainFilter(ControllerName)),
|
||||
Filters: append(eventsTheControllerFollows(), AgainFilter(ControllerName)),
|
||||
Push: true,
|
||||
AckWaitSeconds: 30,
|
||||
MaxDeliver: 5,
|
||||
@@ -463,16 +485,32 @@ func MeshConsumers() []Consumer {
|
||||
MaxAckPending: 1,
|
||||
FromNow: true,
|
||||
// **The one consumer the mesh resets by itself** (healer H4, issue 248): it fell a week
|
||||
// behind once and held every merge after it. What a reset drops is caught up elsewhere —
|
||||
// a merge by the catch-up pass that reads the forge (issue 266), a build's outcome from the
|
||||
// build records a plan settles from (issue 214), a provider's failing word by the provider
|
||||
// saying it again every quarter of an hour (ADR 0224).
|
||||
Resettable: "what it drops is caught up: merges by the catch-up pass (issue 266), build outcomes " +
|
||||
"from the build records (issue 214), a provider's failing word said again (ADR 0224)",
|
||||
// behind once and held every merge after it. What a reset drops is caught up elsewhere — a
|
||||
// build's outcome from the build records a plan settles from (issue 214), a provider's failing
|
||||
// word by the provider saying it again every quarter of an hour (ADR 0224). **Not the merges**:
|
||||
// they are the merges consumer's below, which a reset leaves alone (ADR 0407 decision 3).
|
||||
Resettable: "what it drops is caught up: build outcomes from the build records (issue 214), a " +
|
||||
"provider's failing word said again (ADR 0224); the forge's merges are not its, they have a " +
|
||||
"consumer of their own that no reset touches",
|
||||
Why: "the events the mesh's own controller reacts to, one at a time; after " +
|
||||
"max-deliver it gives the event up, and the controller keeps it in DEAD_LETTERS until " +
|
||||
"a person delivers it again or drops it",
|
||||
},
|
||||
// The forge's merges (novox/hq ADR 0407 decision 3, issue 973): never dropped, so no max-deliver and no
|
||||
// reset; a merge the controller cannot record yet is held with a growing delay until it can.
|
||||
{
|
||||
Name: MergesConsumerName,
|
||||
Stream: "EVENTS",
|
||||
// Within what the controller may subscribe already (`_DELIVER.controller.>`).
|
||||
DeliverSubject: "_DELIVER." + ControllerName + ".merges",
|
||||
Filters: []string{ControllerFollows[3]},
|
||||
Push: true,
|
||||
AckWaitSeconds: 30,
|
||||
MaxAckPending: 1,
|
||||
FromNow: true,
|
||||
Why: "the forge's merges, one at a time; no max-deliver and never reset, because a merge is never " +
|
||||
"dropped and no person releases one",
|
||||
},
|
||||
// What the server said a consumer gave up on (novox/hq issue 330): copied into DEAD_LETTERS and
|
||||
// acknowledged. No max-deliver: a notice the controller could not copy is offered again, and said.
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user