Checker: reads the seat list when its hub is heard while it is unread, since the seat's event before its consumer is lost to it (ADR 0636 §1; issue 1966)
This commit is contained in:
@@ -465,6 +465,8 @@ func run(ctx context.Context, getenv func(string) string, logOut io.Writer) erro
|
||||
// check fails at its publish bound until the checker starts again.
|
||||
if err := hub.Start(ctx, js, cred); err != nil {
|
||||
logger.Printf("%v, so no package registry's published is heard and a group's check fails at its publish bound until the checker starts again", err)
|
||||
} else {
|
||||
readIfUnread(seats.reader)
|
||||
}
|
||||
defer hub.Stop()
|
||||
// The checks, the tries and the hand asks, once every first view is answered (the lead's ruling for DLV-M2): a check
|
||||
|
||||
@@ -49,3 +49,13 @@ func (s seatList) Definitions() ([]json.RawMessage, error) {
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// readIfUnread is called when the checker's hub is heard. The seat may have answered, and said that it does, before the
|
||||
// checker's consumer existed, whose events start at the stream's end: the first read found it silent and nothing else reads
|
||||
// again until its next event, so while the list is unread it is read now, on a goroutine of its own (ADR 0636 §1).
|
||||
func readIfUnread(reader *seatlist.Reader) {
|
||||
if reader == nil || reader.Status().Heard {
|
||||
return
|
||||
}
|
||||
go func() { _ = reader.Reload() }()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"git.novox.be/novox/mesh-sdk/go/seatlist"
|
||||
)
|
||||
|
||||
// silentThenAnswering is a seat that is silent at the reader's first read and answers after.
|
||||
type silentThenAnswering struct{ answering atomic.Bool }
|
||||
|
||||
func (b *silentThenAnswering) Ask(string, any) (json.RawMessage, error) {
|
||||
if !b.answering.Load() {
|
||||
return nil, errors.New("not connected yet")
|
||||
}
|
||||
return json.RawMessage(`{"revision":1,"seats":[]}`), nil
|
||||
}
|
||||
|
||||
func (b *silentThenAnswering) Subscribe(string, func(string, json.RawMessage) error) error { return nil }
|
||||
|
||||
// A seat that spoke before the checker's consumer existed is read when the hub is heard (ADR 0636 §1).
|
||||
func TestTheSeatListIsReadWhenTheHubIsHeard(t *testing.T) {
|
||||
bus := &silentThenAnswering{}
|
||||
reader := followSeatList(bus, t.Logf)
|
||||
<-reader.Ready()
|
||||
if reader.Status().Heard {
|
||||
t.Fatal("a silent seat was heard")
|
||||
}
|
||||
bus.answering.Store(true)
|
||||
readIfUnread(reader)
|
||||
for deadline := time.Now().Add(5 * time.Second); !reader.Status().Heard; time.Sleep(10 * time.Millisecond) {
|
||||
if time.Now().After(deadline) {
|
||||
t.Fatal("the list was not read when the hub was heard")
|
||||
}
|
||||
}
|
||||
var _ seatlist.Bus = bus
|
||||
}
|
||||
Reference in New Issue
Block a user