aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/app/state/state.go
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2025-10-28 23:04:17 +0900
committerOphestra <cat@gensokyo.uk>2025-10-29 03:21:00 +0900
commit65342d588ff061d2130e6379d86a26be90c908ae (patch)
treefb876d53aebe594fe153d1e40aa225508a92a9ef /internal/app/state/state.go
parent5e5826459ed744fc0bd717e0136614365c7a96f3 (diff)
internal/app/state: improve store internals
This fully exposes the store internals for #19 and are final preparations for removing the legacy store interface. This change also fixes a potential deadlock in the handle initialisation mkdir failure path. This however is never reachable in hakurei as the store is never accessed concurrently. Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal/app/state/state.go')
-rw-r--r--internal/app/state/state.go41
1 files changed, 37 insertions, 4 deletions
diff --git a/internal/app/state/state.go b/internal/app/state/state.go
index 169af507..62b31865 100644
--- a/internal/app/state/state.go
+++ b/internal/app/state/state.go
@@ -6,7 +6,6 @@ import (
"hakurei.app/container/check"
"hakurei.app/hst"
- "hakurei.app/internal/lockedfile"
"hakurei.app/message"
)
@@ -23,11 +22,45 @@ type Store interface {
List() (identities []int, err error)
}
+func (s *stateStore) Do(identity int, f func(c Cursor)) (bool, error) {
+ if h, err := s.identityHandle(identity); err != nil {
+ return false, err
+ } else {
+ return h.do(f)
+ }
+}
+
+// storeAdapter satisfies [Store] via stateStore.
+type storeAdapter struct {
+ msg message.Msg
+ *stateStore
+}
+
+func (s storeAdapter) List() ([]int, error) {
+ segments, n, err := s.segments()
+ if err != nil {
+ return nil, err
+ }
+
+ identities := make([]int, 0, n)
+ for si := range segments {
+ if si.err != nil {
+ if m, ok := message.GetMessage(err); ok {
+ s.msg.Verbose(m)
+ } else {
+ // unreachable
+ return nil, err
+ }
+ continue
+ }
+ identities = append(identities, si.identity)
+ }
+ return identities, nil
+}
+
// NewMulti returns an instance of the multi-file store.
func NewMulti(msg message.Msg, prefix *check.Absolute) Store {
- store := &stateStore{msg: msg, base: prefix.Append("state")}
- store.fileMu = lockedfile.MutexAt(store.base.Append(storeMutexName).String())
- return store
+ return storeAdapter{msg, newStore(prefix.Append("state"))}
}
// Cursor provides access to the store of an identity.