views.ProcessReader.HolderBucket names the holder's real bucket of a seat's view FollowSeat follows
mesh/delivery-group group feat/47-G-join11 checking: 17 of 17 member(s) ready
mesh/delivery closed: a newer head of the same pull request
mesh/check checking cb5e62dfacd9 on 8fbba810609e | novox/mesh-sdk#189 in group feat/47-G-join11

A part that follows a seat's view names its picture in the seat form, but where another part names the holder's own
bucket (the watchman's stuck key of the assigner's wants) the name must be the holder's: HolderBucket answers
`<holder>_<state>` of the holder followed now, "" while none, read at each use so a moved holder is named as it moves.

Builds: design 47 G §717, A-303 (corrected)

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
2026-11-12 20:32:16 +01:00
parent ed46f5da6a
commit cb5e62dfac
2 changed files with 27 additions and 0 deletions
+18
View File
@@ -273,6 +273,24 @@ func (r *ProcessReader) hand(sw *seatFollow, inner *Picture) {
}
}
// HolderBucket is the bus name `<holder>_<state>` of the holder whose state FollowSeat follows now for seat, "" while it
// follows none (design 47 G A-303): the name a part uses where another part names the holder's real bucket (a key the
// watchman writes, a name kept in an entry), read at each use, so a moved holder is named as it moves.
func (r *ProcessReader) HolderBucket(seat, state string) string {
r.mu.Lock()
sw := r.seats[seat+"_"+state]
r.mu.Unlock()
if sw == nil {
return ""
}
sw.mu.Lock()
defer sw.mu.Unlock()
if sw.holder == "" {
return ""
}
return sw.holder + "_" + state
}
// seatPicture is the picture of a seat's view by its bus name, nil when none.
func (r *ProcessReader) seatPicture(bucket string) *Picture {
r.mu.Lock()
+9
View File
@@ -1023,6 +1023,9 @@ func subViews(t *testing.T) {
if _, err := p.Get(context.Background(), "hold.a"); err == nil {
t.Errorf("a seat's view with no holder reads as held")
}
if b := r.HolderBucket("mesh-wants", "asks"); b != "" {
t.Errorf("with no holder the holder's bucket is %q", b)
}
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
r.Ask(ctx, nil)
@@ -1054,6 +1057,9 @@ func subViews(t *testing.T) {
sh.Follower().Apply(Event{V: Version, Owner: "assigner", State: "seat-holders", Key: "mesh-wants", Revision: 2, Created: made,
Value: json.RawMessage(`{"holders":[{"module":"h1"}]}`)})
ready(`{"n":1}`)
if b := r.HolderBucket("mesh-wants", "asks"); b != "h1_asks" { // A-303: the holder's real bucket, at run time
t.Errorf("the holder's bucket is %q, want h1_asks", b)
}
if len(fs.m) != 0 {
t.Errorf("the holder's first view left the findings %v", fs.m)
}
@@ -1069,6 +1075,9 @@ func subViews(t *testing.T) {
sh.Follower().Apply(Event{V: Version, Owner: "assigner", State: "seat-holders", Key: "mesh-wants", Revision: 3, Created: made,
Value: json.RawMessage(`{"holders":[{"module":"h2"}]}`)})
ready(`{"n":3}`)
if b := r.HolderBucket("mesh-wants", "asks"); b != "h2_asks" {
t.Errorf("after the move the holder's bucket is %q, want h2_asks", b)
}
if keys, _ := p.Keys(ctx); strings.Join(keys, ",") != "hold.a" || r.Picture("h1_asks") != nil {
t.Errorf("after the move the picture holds %v, h1 followed %v", keys, r.Picture("h1_asks") != nil)
}