process: read a state its owner keeps one bucket per node as one state, so the provisioner, the assigner and the view read every node's compositions (ADR 0593 §6)
Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
This commit is contained in:
+18
-7
@@ -28,6 +28,8 @@ const stateTimeout = 30 * time.Second
|
||||
type State struct {
|
||||
Module string
|
||||
Name string
|
||||
// bucketName is the bucket when it is not <module>_<name>: one node's bucket of a per-node state (NodeFamily).
|
||||
bucketName string
|
||||
// kv binds this state's underlying key-value store: a live connection's own (Conn.State), or, in a
|
||||
// unit test, a fake that never reaches a bus.
|
||||
kv func(ctx context.Context) (jetstream.KeyValue, error)
|
||||
@@ -36,14 +38,19 @@ type State struct {
|
||||
}
|
||||
|
||||
// bucket is this state's name on the bus.
|
||||
func (s State) bucket() string { return s.Module + "_" + s.Name }
|
||||
func (s State) bucket() string {
|
||||
if s.bucketName != "" {
|
||||
return s.bucketName
|
||||
}
|
||||
return s.Module + "_" + s.Name
|
||||
}
|
||||
|
||||
// State is the named state this connection's module keeps, bound lazily to its bucket on each call so a
|
||||
// bucket the account is not granted fails at the call that needed it, naming the bucket. The bind itself
|
||||
// (js.KeyValue) is what asks $JS.API.STREAM.INFO.KV_<bucket>, so it is what withRefusal watches: a bucket
|
||||
// not granted is refused there, promptly, as nats.ErrPermissionViolation.
|
||||
func (c *Conn) State(name string) State {
|
||||
return c.bound(c.account.Module, name, func() error { return c.refusedUnannounced(name) })
|
||||
return c.bound(c.account.Module, name, "", func() error { return c.refusedUnannounced(name) })
|
||||
}
|
||||
|
||||
// Read is another module's state this connection's module reads, named as its manifest's `reads` names it
|
||||
@@ -52,7 +59,7 @@ func (c *Conn) State(name string) State {
|
||||
// the seat mesh-provisioner's plans). A name that is not `<module>.<state>` fails at the call that needed it.
|
||||
func (c *Conn) Read(read string) State {
|
||||
module, name, ok := strings.Cut(read, ".")
|
||||
return c.bound(module, name, func() error {
|
||||
return c.bound(module, name, "", func() error {
|
||||
if !ok || module == "" || name == "" || strings.Contains(name, ".") {
|
||||
return fmt.Errorf("%q is not a state another module keeps, <module>.<state>", read)
|
||||
}
|
||||
@@ -60,10 +67,14 @@ func (c *Conn) Read(read string) State {
|
||||
})
|
||||
}
|
||||
|
||||
// bound is module's state name on this connection, checked by refused before every bind.
|
||||
func (c *Conn) bound(module, name string, refused func() error) State {
|
||||
bucket := module + "_" + name
|
||||
return State{Module: module, Name: name, closed: func() bool { return c.nc.IsClosed() }, kv: func(ctx context.Context) (jetstream.KeyValue, error) {
|
||||
// bound is module's state name on this connection, in its bucket <module>_<name> or the bucket given, checked by
|
||||
// refused before every bind.
|
||||
func (c *Conn) bound(module, name, bucket string, refused func() error) State {
|
||||
given := bucket
|
||||
if bucket == "" {
|
||||
bucket = module + "_" + name
|
||||
}
|
||||
return State{Module: module, Name: name, bucketName: given, closed: func() bool { return c.nc.IsClosed() }, kv: func(ctx context.Context) (jetstream.KeyValue, error) {
|
||||
if err := refused(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user