Add output to persisted engine run, add code docs
This commit is contained in:
parent
1844415ae9
commit
12ff703bc9
@ -9,6 +9,16 @@ import (
|
|||||||
"git.defalsify.org/festive/resource"
|
"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 {
|
func RunPersisted(cfg Config, rs resource.Resource, pr persist.Persister, input []byte, w io.Writer, ctx context.Context) error {
|
||||||
err := pr.Load(cfg.SessionId)
|
err := pr.Load(cfg.SessionId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -24,5 +34,5 @@ func RunPersisted(cfg Config, rs resource.Resource, pr persist.Persister, input
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return en.WriteResult(w, ctx)
|
||||||
}
|
}
|
||||||
|
@ -11,12 +11,16 @@ import (
|
|||||||
"git.defalsify.org/festive/state"
|
"git.defalsify.org/festive/state"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// FsPersister is an implementation of Persister that saves state to the file system.
|
||||||
type FsPersister struct {
|
type FsPersister struct {
|
||||||
State *state.State
|
State *state.State
|
||||||
Memory *cache.Cache
|
Memory *cache.Cache
|
||||||
dir string
|
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 {
|
func NewFsPersister(dir string) *FsPersister {
|
||||||
fp, err := filepath.Abs(dir)
|
fp, err := filepath.Abs(dir)
|
||||||
if err != nil {
|
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 {
|
func(p *FsPersister) WithContent(st *state.State, ca *cache.Cache) *FsPersister {
|
||||||
p.State = st
|
p.State = st
|
||||||
p.Memory = ca
|
p.Memory = ca
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetState implements the Persister interface.
|
||||||
func(p *FsPersister) GetState() *state.State {
|
func(p *FsPersister) GetState() *state.State {
|
||||||
return p.State
|
return p.State
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetState implements the Persister interface.
|
||||||
func(p *FsPersister) GetMemory() cache.Memory {
|
func(p *FsPersister) GetMemory() cache.Memory {
|
||||||
return p.Memory
|
return p.Memory
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetState implements the Persister interface.
|
||||||
func(p *FsPersister) Serialize() ([]byte, error) {
|
func(p *FsPersister) Serialize() ([]byte, error) {
|
||||||
return cbor.Marshal(p)
|
return cbor.Marshal(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetState implements the Persister interface.
|
||||||
func(p *FsPersister) Deserialize(b []byte) error {
|
func(p *FsPersister) Deserialize(b []byte) error {
|
||||||
err := cbor.Unmarshal(b, p)
|
err := cbor.Unmarshal(b, p)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetState implements the Persister interface.
|
||||||
func(p *FsPersister) Save(key string) error {
|
func(p *FsPersister) Save(key string) error {
|
||||||
b, err := p.Serialize()
|
b, err := p.Serialize()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -60,6 +72,7 @@ func(p *FsPersister) Save(key string) error {
|
|||||||
return ioutil.WriteFile(fp, b, 0600)
|
return ioutil.WriteFile(fp, b, 0600)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetState implements the Persister interface.
|
||||||
func(p *FsPersister) Load(key string) error {
|
func(p *FsPersister) Load(key string) error {
|
||||||
fp := path.Join(p.dir, key)
|
fp := path.Join(p.dir, key)
|
||||||
b, err := ioutil.ReadFile(fp)
|
b, err := ioutil.ReadFile(fp)
|
||||||
|
@ -5,12 +5,13 @@ import (
|
|||||||
"git.defalsify.org/festive/state"
|
"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 {
|
type Persister interface {
|
||||||
Serialize() ([]byte, error)
|
Serialize() ([]byte, error) // Output serializes representation of the state.
|
||||||
Deserialize(b []byte) error
|
Deserialize(b []byte) error // Restore state from a serialized state.
|
||||||
Save(key string) error
|
Save(key string) error // Serialize and commit the state representation to persisted storage.
|
||||||
Load(key string) error
|
Load(key string) error // Load the state representation from persisted storage and Deserialize.
|
||||||
GetState() *state.State
|
GetState() *state.State // Get the currently loaded State object.
|
||||||
GetMemory() cache.Memory
|
GetMemory() cache.Memory // Get the currently loaded Cache object.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,10 +4,11 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Result contains the results of an external code operation.
|
||||||
type Result struct {
|
type Result struct {
|
||||||
Content string
|
Content string // content value for symbol after execution.
|
||||||
FlagSet []uint32
|
FlagSet []uint32 // request caller to set error flags at given indices.
|
||||||
FlagReset []uint32
|
FlagReset []uint32 // request caller to reset error flags at given indices.
|
||||||
}
|
}
|
||||||
|
|
||||||
// EntryFunc is a function signature for retrieving value for a key
|
// 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.
|
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 {
|
type MenuResource struct {
|
||||||
sinkValues []string
|
sinkValues []string
|
||||||
codeFunc CodeFunc
|
codeFunc CodeFunc
|
||||||
@ -53,14 +57,17 @@ func(m *MenuResource) WithTemplateGetter(templateGetter TemplateFunc) *MenuResou
|
|||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FuncFor implements Resource interface
|
||||||
func(m *MenuResource) FuncFor(sym string) (EntryFunc, error) {
|
func(m *MenuResource) FuncFor(sym string) (EntryFunc, error) {
|
||||||
return m.funcFunc(sym)
|
return m.funcFunc(sym)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetCode implements Resource interface
|
||||||
func(m *MenuResource) GetCode(sym string) ([]byte, error) {
|
func(m *MenuResource) GetCode(sym string) ([]byte, error) {
|
||||||
return m.codeFunc(sym)
|
return m.codeFunc(sym)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetTemplate implements Resource interface
|
||||||
func(m *MenuResource) GetTemplate(sym string) (string, error) {
|
func(m *MenuResource) GetTemplate(sym string) (string, error) {
|
||||||
return m.templateFunc(sym)
|
return m.templateFunc(sym)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user