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>
This commit is contained in:
2025-10-28 23:04:17 +09:00
parent 5e5826459e
commit 65342d588f
5 changed files with 382 additions and 72 deletions

View File

@@ -1,17 +1,22 @@
package state_test
import (
"math/rand/v2"
"log"
"math/rand"
"reflect"
"slices"
"testing"
"time"
"hakurei.app/container/check"
"hakurei.app/hst"
"hakurei.app/internal/app/state"
"hakurei.app/message"
)
func testStore(t *testing.T, s state.Store) {
func TestMulti(t *testing.T) {
s := state.NewMulti(message.NewMsg(log.New(log.Writer(), "multi: ", 0)), check.MustAbs(t.TempDir()))
t.Run("list empty store", func(t *testing.T) {
if identities, err := s.List(); err != nil {
t.Fatalf("List: error = %v", err)
@@ -30,7 +35,12 @@ func testStore(t *testing.T, s state.Store) {
var tc [tl]hst.State
for i := 0; i < tl; i++ {
makeState(t, &tc[i])
if err := hst.NewInstanceID(&tc[i].ID); err != nil {
t.Fatalf("cannot create dummy state: %v", err)
}
tc[i].PID = rand.Int()
tc[i].Config = hst.Template()
tc[i].Time = time.Now()
}
do := func(identity int, f func(c state.Cursor)) {
@@ -108,12 +118,3 @@ func testStore(t *testing.T, s state.Store) {
}
})
}
func makeState(t *testing.T, s *hst.State) {
if err := hst.NewInstanceID(&s.ID); err != nil {
t.Fatalf("cannot create dummy state: %v", err)
}
s.PID = rand.Int()
s.Config = hst.Template()
s.Time = time.Now()
}