mesh-issues: an open whose write may have landed never says nothing was opened, and a module must itself be registered
mesh/merge-gate pass: builds new: modules/mesh-issues, sent nowhere; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-check-typescript.sh (typescript)
mesh/delivery delivered
mesh/merge-gate pass: builds new: modules/mesh-issues, sent nowhere; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-check-typescript.sh (typescript)
mesh/delivery delivered
From the review: a taken key that cannot be read back, or a write never confirmed, now tells the caller to get the number before opening again; an owner entry naming a module is owned only by that module registered; link targets get the secret guard; line separators are refused in one-line fields; the acceptance test now proves the counter's own updates were contended.
This commit is contained in:
@@ -43,9 +43,11 @@ func TestMain(m *testing.M) {
|
||||
type bus struct {
|
||||
// lost counts the compare-and-sets another writer won: proof the openers collided.
|
||||
lost atomic.Int64
|
||||
nc *nats.Conn
|
||||
js jetstream.JetStream
|
||||
kvs map[string]jetstream.KeyValue
|
||||
// counterLost counts only the counter's updates another opener won: proof the counter itself was contended.
|
||||
counterLost atomic.Int64
|
||||
nc *nats.Conn
|
||||
js jetstream.JetStream
|
||||
kvs map[string]jetstream.KeyValue
|
||||
}
|
||||
|
||||
func newBus(t *testing.T) *bus {
|
||||
@@ -243,6 +245,9 @@ func (i *instance) answer(m rpc) {
|
||||
errors.As(err, &api) && api.ErrorCode == jetstream.JSErrCodeStreamWrongLastSequence {
|
||||
code = -32010
|
||||
i.b.lost.Add(1)
|
||||
if m.Method == "mesh/state.update" && p.State == CountersState {
|
||||
i.b.counterLost.Add(1)
|
||||
}
|
||||
}
|
||||
i.say(map[string]any{"id": m.ID, "error": map[string]any{"code": code, "message": err.Error()}})
|
||||
return
|
||||
@@ -336,9 +341,10 @@ func TestFiftyOpensAtOnceFromTwoInstancesGetFiftyDistinctConsecutiveNumbers(t *t
|
||||
}
|
||||
}
|
||||
// The openers collided: writes were refused because another opener had moved the counter first.
|
||||
t.Logf("%d writes lost to another opener and tried again", b.lost.Load())
|
||||
if b.lost.Load() == 0 {
|
||||
t.Fatal("no opener ever lost a write: the test did not make them collide")
|
||||
t.Logf("%d writes lost to another opener and tried again, %d of them the counter's updates", b.lost.Load(), b.counterLost.Load())
|
||||
if b.counterLost.Load() < opens {
|
||||
t.Fatalf("only %d of the counter's updates were lost to another opener: the test did not make the openers "+
|
||||
"contend for the counter", b.counterLost.Load())
|
||||
}
|
||||
ctx := context.Background()
|
||||
e, err := b.kvs[CountersState].Get(ctx, IssueCounter)
|
||||
|
||||
Reference in New Issue
Block a user