go-vise

Constrained Size Output Virtual Machine
Info | Log | Files | Refs | README | LICENSE

commit 03876d1a78bd42333f1cab527776dc6a9f274cea
parent 15fe28c9d5b0a380c071f001953b7dfbb1997952
Author: lash <dev@holbrook.no>
Date:   Tue, 10 Sep 2024 23:02:39 +0100

Add flush after save option for persister

Diffstat:
Mdb/gdbm/gdbm.go | 5++++-
Mengine/config.go | 9+++++++++
Mpersist/persist.go | 27++++++++++++++++++++++++---
Mstate/state.go | 5+++++
4 files changed, 42 insertions(+), 4 deletions(-)

diff --git a/db/gdbm/gdbm.go b/db/gdbm/gdbm.go @@ -54,6 +54,7 @@ func(gdb *gdbmDb) Connect(ctx context.Context, connStr string) error { if err != nil { return err } + logg.DebugCtxf(ctx, "gdbm connected", "connstr", connStr) gdb.conn = db return nil } @@ -97,10 +98,12 @@ func(gdb *gdbmDb) Get(ctx context.Context, key []byte) ([]byte, error) { } return nil, err } + logg.TraceCtxf(ctx, "gdbm get", "key", key, "lk", lk, "val", v) return v, nil } // Close implements Db func(gdb *gdbmDb) Close() error { - return gdb.Close() + logg.Tracef("closing gdbm", "path", gdb.conn) + return gdb.conn.Close() } diff --git a/engine/config.go b/engine/config.go @@ -1,5 +1,9 @@ package engine +import ( + "fmt" +) + // Config globally defines behavior of all components driven by the engine. type Config struct { // OutputSize sets the maximum size of output from a single rendered page. If set to 0, no size limit is imposed. @@ -19,3 +23,8 @@ type Config struct { // EngineDebug activates the engine debug output EngineDebug bool } + +// String implements the string interface. +func(c Config) String() string { + return fmt.Sprintf("sessionid '%s', rootpath '%s', flagcount %d, language '%s'", c.SessionId, c.Root, c.FlagCount, c.Language) +} diff --git a/persist/persist.go b/persist/persist.go @@ -16,6 +16,7 @@ type Persister struct { Memory *cache.Cache ctx context.Context db db.Db + flush bool } // NewPersister creates a new Persister instance. @@ -39,7 +40,7 @@ func(p *Persister) WithSession(sessionId string) *Persister { } -// WithContent sets a current State and Cache object. +// WithContent is a chainable function that sets a current State and Cache object. // // This method is normally called before Serialize / Save. func(p *Persister) WithContent(st *state.State, ca *cache.Cache) *Persister { @@ -48,6 +49,13 @@ func(p *Persister) WithContent(st *state.State, ca *cache.Cache) *Persister { return p } +// WithFlush is a chainable function that instructs the persister to flush its memory and state +// after successful Save. +func(p *Persister) WithFlush() *Persister { + p.flush = true + return p +} + // Invalid checks if the underlying state has been invalidated. // // An invalid state will cause Save to panic. @@ -77,6 +85,9 @@ func(p *Persister) Deserialize(b []byte) error { } // Save perists the state and cache to the db.Db backend. +// +// If save is successful and WithFlush() has been called, the state and memory +// will be empty when the method returns. func(p *Persister) Save(key string) error { if p.Invalid() { panic("persister has been invalidated") @@ -86,7 +97,17 @@ func(p *Persister) Save(key string) error { return err } p.db.SetPrefix(db.DATATYPE_STATE) - return p.db.Put(p.ctx, []byte(key), b) + logg.Debugf("saving state and cache", "key", key, "state", p.State) + err = p.db.Put(p.ctx, []byte(key), b) + if err != nil { + return err + } + if p.flush { + logg.Tracef("state and cache flushed from persister") + p.Memory.Reset() + p.State = p.State.CloneEmpty() + } + return nil } // Load retrieves state and cache from the db.Db backend. @@ -100,6 +121,6 @@ func(p *Persister) Load(key string) error { if err != nil { return err } - logg.Debugf("loaded state and cache", "key", key, "bytecode", p.State.Code) + logg.Debugf("loaded state and cache", "key", key, "state", p.State) return nil } diff --git a/state/state.go b/state/state.go @@ -379,6 +379,11 @@ func(st *State) SetLanguage(code string) error { return nil } +func(st *State) CloneEmpty() *State { + flagCount := st.BitSize - 8 + return NewState(flagCount) +} + // String implements String interface func(st State) String() string { var flags string