Two consumers may share a name; they must not share a delivery subject
novox/hq 04-ISSUES/146. A push consumer delivers onto an ordinary subject and everything subscribed to it gets a copy. The controller holds a consumer called 'controller' on CONTROL and another called 'controller' on EVENTS, and both were given _DELIVER.controller — so the one process, holding both subscriptions, acted on every message twice. Measured: one enrolment published, one message in the stream, one delivery, no redelivery, and the controller enrolled the machine twice — the second minting a credential that replaced the one the machine had just been handed, which is why it then reconnected for ever as a user whose password the mesh had rotated. Every report and every followed event doubled the same way, silently. The stream goes in the subject because the pair is what identifies a consumer. A subscriber's permission gains the same shape, keeping the bare name so an existing consumer keeps working until the next assertion moves it.
This commit is contained in:
@@ -233,3 +233,30 @@ func containsStep(steps []string, want string) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// **Two consumers may share a name, and must not share a delivery subject** (novox/hq
|
||||
// 04-ISSUES/146).
|
||||
//
|
||||
// A push consumer delivers onto an ordinary subject and everything subscribed to it gets a copy.
|
||||
// The controller holds a consumer called `controller` on CONTROL and another called `controller` on
|
||||
// EVENTS; while both were given `_DELIVER.controller`, the one process holding both subscriptions
|
||||
// acted on every message twice — a joining machine enrolled twice from one request, with the second
|
||||
// enrolment minting a credential that replaced the one the machine had just been handed.
|
||||
//
|
||||
// Checked here rather than against a server because it is a property of what the mesh asks for, and
|
||||
// because the failure it produces is silent: every count is right, nothing is redelivered, and the
|
||||
// work simply happens twice.
|
||||
func TestNoTwoConsumersDeliverOntoTheSameSubject(t *testing.T) {
|
||||
seen := map[string]string{}
|
||||
for _, c := range MeshConsumers() {
|
||||
if !c.Push && c.Queue == "" {
|
||||
continue
|
||||
}
|
||||
subject := DeliverSubjectFor(c)
|
||||
if other, taken := seen[subject]; taken {
|
||||
t.Errorf("%s on %s and %s deliver onto %s, so whoever holds both acts on every "+
|
||||
"message twice", c.Name, c.Stream, other, subject)
|
||||
}
|
||||
seen[subject] = c.Name + " on " + c.Stream
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user