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:
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