commit 12ff703bc962911dad0f7c5e86ee7584cd64e966
parent 1844415ae94840dbac2065b9e204f3737e093460
Author: lash <dev@holbrook.no>
Date: Thu, 13 Apr 2023 09:38:35 +0100
Add output to persisted engine run, add code docs
Diffstat:
4 files changed, 41 insertions(+), 10 deletions(-)
diff --git a/engine/persist.go b/engine/persist.go
@@ -9,6 +9,16 @@ import (
"git.defalsify.org/festive/resource"
)
+// RunPersisted performs a single vm execution from client input using a persisted state.
+//
+// State is first loaded from storage. The vm is initialized with the state and executed. The new state is then saved to storage.
+//
+// The resulting output of the execution will be written to the provided writer.
+//
+// The state is identified by the SessionId member of the Config. Before first execution, the caller must ensure that an
+// initialized state actually is available for the identifier, otherwise the method will fail.
+//
+// It will also fail if execution by the underlying Engine fails.
func RunPersisted(cfg Config, rs resource.Resource, pr persist.Persister, input []byte, w io.Writer, ctx context.Context) error {
err := pr.Load(cfg.SessionId)
if err != nil {
@@ -24,5 +34,5 @@ func RunPersisted(cfg Config, rs resource.Resource, pr persist.Persister, input
return err
}
}
- return nil
+ return en.WriteResult(w, ctx)
}
diff --git a/persist/fs.go b/persist/fs.go
@@ -11,12 +11,16 @@ import (
"git.defalsify.org/festive/state"
)
+// FsPersister is an implementation of Persister that saves state to the file system.
type FsPersister struct {
State *state.State
Memory *cache.Cache
dir string
}
+// NewFsPersister creates a new FsPersister.
+//
+// The filesystem store will be at the given directory. The directory must exist.
func NewFsPersister(dir string) *FsPersister {
fp, err := filepath.Abs(dir)
if err != nil {
@@ -27,29 +31,37 @@ func NewFsPersister(dir string) *FsPersister {
}
}
+// WithContent sets a current State and Cache object.
+//
+// This method is normally called before Serialize / Save.
func(p *FsPersister) WithContent(st *state.State, ca *cache.Cache) *FsPersister {
p.State = st
p.Memory = ca
return p
}
+// GetState implements the Persister interface.
func(p *FsPersister) GetState() *state.State {
return p.State
}
+// GetState implements the Persister interface.
func(p *FsPersister) GetMemory() cache.Memory {
return p.Memory
}
+// GetState implements the Persister interface.
func(p *FsPersister) Serialize() ([]byte, error) {
return cbor.Marshal(p)
}
+// GetState implements the Persister interface.
func(p *FsPersister) Deserialize(b []byte) error {
err := cbor.Unmarshal(b, p)
return err
}
+// GetState implements the Persister interface.
func(p *FsPersister) Save(key string) error {
b, err := p.Serialize()
if err != nil {
@@ -60,6 +72,7 @@ func(p *FsPersister) Save(key string) error {
return ioutil.WriteFile(fp, b, 0600)
}
+// GetState implements the Persister interface.
func(p *FsPersister) Load(key string) error {
fp := path.Join(p.dir, key)
b, err := ioutil.ReadFile(fp)
diff --git a/persist/persist.go b/persist/persist.go
@@ -5,12 +5,13 @@ import (
"git.defalsify.org/festive/state"
)
+// Persister interface defines the methods needed for a component that can store the execution state to a storage location.
type Persister interface {
- Serialize() ([]byte, error)
- Deserialize(b []byte) error
- Save(key string) error
- Load(key string) error
- GetState() *state.State
- GetMemory() cache.Memory
+ Serialize() ([]byte, error) // Output serializes representation of the state.
+ Deserialize(b []byte) error // Restore state from a serialized state.
+ Save(key string) error // Serialize and commit the state representation to persisted storage.
+ Load(key string) error // Load the state representation from persisted storage and Deserialize.
+ GetState() *state.State // Get the currently loaded State object.
+ GetMemory() cache.Memory // Get the currently loaded Cache object.
}
diff --git a/resource/resource.go b/resource/resource.go
@@ -4,10 +4,11 @@ import (
"context"
)
+// Result contains the results of an external code operation.
type Result struct {
- Content string
- FlagSet []uint32
- FlagReset []uint32
+ Content string // content value for symbol after execution.
+ FlagSet []uint32 // request caller to set error flags at given indices.
+ FlagReset []uint32 // request caller to reset error flags at given indices.
}
// EntryFunc is a function signature for retrieving value for a key
@@ -23,6 +24,9 @@ type Resource interface {
FuncFor(sym string) (EntryFunc, error) // Resolve symbol content point for.
}
+// MenuResource contains the base definition for building Resource implementations.
+//
+// TODO: Rename to BaseResource
type MenuResource struct {
sinkValues []string
codeFunc CodeFunc
@@ -53,14 +57,17 @@ func(m *MenuResource) WithTemplateGetter(templateGetter TemplateFunc) *MenuResou
return m
}
+// FuncFor implements Resource interface
func(m *MenuResource) FuncFor(sym string) (EntryFunc, error) {
return m.funcFunc(sym)
}
+// GetCode implements Resource interface
func(m *MenuResource) GetCode(sym string) ([]byte, error) {
return m.codeFunc(sym)
}
+// GetTemplate implements Resource interface
func(m *MenuResource) GetTemplate(sym string) (string, error) {
return m.templateFunc(sym)
}