diff --git a/go/views/follow_seat.go b/go/views/follow_seat.go index 974eee90..a3ca3159 100644 --- a/go/views/follow_seat.go +++ b/go/views/follow_seat.go @@ -273,6 +273,24 @@ func (r *ProcessReader) hand(sw *seatFollow, inner *Picture) { } } +// HolderBucket is the bus name `_` 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() diff --git a/go/views/views_test.go b/go/views/views_test.go index 806f67c4..bd4ef33e 100644 --- a/go/views/views_test.go +++ b/go/views/views_test.go @@ -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) }