internal/app/state: include et header
All checks were successful
Test / Create distribution (push) Successful in 35s
Test / Sandbox (push) Successful in 2m17s
Test / Hakurei (push) Successful in 3m5s
Test / Hpkg (push) Successful in 3m55s
Test / Sandbox (race detector) (push) Successful in 4m2s
Test / Hakurei (race detector) (push) Successful in 4m49s
Test / Flake checks (push) Successful in 1m22s
All checks were successful
Test / Create distribution (push) Successful in 35s
Test / Sandbox (push) Successful in 2m17s
Test / Hakurei (push) Successful in 3m5s
Test / Hpkg (push) Successful in 3m55s
Test / Sandbox (race detector) (push) Successful in 4m2s
Test / Hakurei (race detector) (push) Successful in 4m49s
Test / Flake checks (push) Successful in 1m22s
This is the initial step of implementing #19. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
parent
470e545d27
commit
fe2929d5f7
@ -117,7 +117,7 @@ type multiBackend struct {
|
||||
|
||||
func (b *multiBackend) filename(id *hst.ID) string { return path.Join(b.path, id.String()) }
|
||||
|
||||
// reads all launchers in simpleBackend
|
||||
// reads all launchers in multiBackend
|
||||
// file contents are ignored if decode is false
|
||||
func (b *multiBackend) load(decode bool) (map[hst.ID]*hst.State, error) {
|
||||
b.mu.RLock()
|
||||
@ -161,18 +161,22 @@ func (b *multiBackend) load(decode bool) (map[hst.ID]*hst.State, error) {
|
||||
|
||||
// append regardless, but only parse if required, implements Len
|
||||
if decode {
|
||||
if err = gob.NewDecoder(f).Decode(&s); err != nil {
|
||||
var et hst.Enablement
|
||||
if et, err = entryReadHeader(f); err != nil {
|
||||
_ = f.Close()
|
||||
return &hst.AppError{Step: "decode state data", Err: err}
|
||||
return &hst.AppError{Step: "decode state header", Err: err}
|
||||
} else if err = gob.NewDecoder(f).Decode(&s); err != nil {
|
||||
_ = f.Close()
|
||||
return &hst.AppError{Step: "decode state body", Err: err}
|
||||
} else if s.ID != id {
|
||||
_ = f.Close()
|
||||
return fmt.Errorf("state entry %s has unexpected id %s", id, &s.ID)
|
||||
} else if err = f.Close(); err != nil {
|
||||
return &hst.AppError{Step: "close state file", Err: err}
|
||||
}
|
||||
|
||||
if s.Config == nil {
|
||||
return ErrNoConfig
|
||||
} else if err = s.Config.Validate(); err != nil {
|
||||
return err
|
||||
} else if s.Enablements.Unwrap() != et {
|
||||
return fmt.Errorf("state entry %s has unexpected enablement byte %x, %x", id, s.Enablements, et)
|
||||
}
|
||||
}
|
||||
|
||||
@ -186,22 +190,24 @@ func (b *multiBackend) load(decode bool) (map[hst.ID]*hst.State, error) {
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// Save writes process state to filesystem
|
||||
// Save writes process state to filesystem.
|
||||
func (b *multiBackend) Save(state *hst.State) error {
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
|
||||
if state.Config == nil {
|
||||
return ErrNoConfig
|
||||
if err := state.Config.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
statePath := b.filename(&state.ID)
|
||||
|
||||
if f, err := os.OpenFile(statePath, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600); err != nil {
|
||||
return &hst.AppError{Step: "create state file", Err: err}
|
||||
} else if err = entryWriteHeader(f, state.Enablements.Unwrap()); err != nil {
|
||||
_ = f.Close()
|
||||
return &hst.AppError{Step: "encode state header", Err: err}
|
||||
} else if err = gob.NewEncoder(f).Encode(state); err != nil {
|
||||
_ = f.Close()
|
||||
return &hst.AppError{Step: "encode state data", Err: err}
|
||||
return &hst.AppError{Step: "encode state body", Err: err}
|
||||
} else if err = f.Close(); err != nil {
|
||||
return &hst.AppError{Step: "close state file", Err: err}
|
||||
}
|
||||
|
||||
@ -2,14 +2,9 @@
|
||||
package state
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"hakurei.app/hst"
|
||||
)
|
||||
|
||||
// ErrNoConfig is returned by [Cursor] when used with a nil [hst.Config].
|
||||
var ErrNoConfig = errors.New("state does not contain config")
|
||||
|
||||
type Store interface {
|
||||
// Do calls f exactly once and ensures store exclusivity until f returns.
|
||||
// Returns whether f is called and any errors during the locking process.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user