visedriver/handlers/base.go

180 lines
5.0 KiB
Go
Raw Normal View History

package handlers
import (
2025-01-10 15:04:23 +01:00
"context"
"fmt"
"git.defalsify.org/vise.git/asm"
"git.defalsify.org/vise.git/db"
2025-01-10 15:04:23 +01:00
"git.defalsify.org/vise.git/state"
"git.defalsify.org/vise.git/cache"
"git.defalsify.org/vise.git/engine"
"git.defalsify.org/vise.git/persist"
"git.defalsify.org/vise.git/resource"
2025-01-05 12:17:58 +01:00
"git.defalsify.org/vise.git/logging"
"git.grassecon.net/grassrootseconomics/visedriver/request"
"git.grassecon.net/grassrootseconomics/visedriver/errors"
2025-01-10 15:04:23 +01:00
dbstorage "git.grassecon.net/grassrootseconomics/visedriver/storage/db"
"git.grassecon.net/grassrootseconomics/visedriver/common"
"git.grassecon.net/grassrootseconomics/visedriver/storage"
2025-01-10 15:04:23 +01:00
"git.grassecon.net/grassrootseconomics/visedriver/remote"
"git.grassecon.net/grassrootseconomics/visedriver/models"
"git.grassecon.net/grassrootseconomics/visedriver/utils"
)
2025-01-05 12:17:58 +01:00
var (
logg = logging.NewVanilla().WithDomain("handlers")
)
2025-01-10 13:03:37 +01:00
type Handlers struct {
pe *persist.Persister
st *state.State
ca cache.Memory
userdataStore common.DataStore
adminstore *utils.AdminStore
flagManager *asm.FlagParser
accountService remote.AccountServiceInterface
prefixDb dbstorage.PrefixDb
profile *models.Profile
ReplaceSeparatorFunc func(string) string
}
2025-01-10 15:04:23 +01:00
// NewHandlers creates a new instance of the Handlers struct with the provided dependencies.
func NewHandlers(appFlags *asm.FlagParser, userdataStore db.Db, adminstore *utils.AdminStore, accountService remote.AccountServiceInterface, replaceSeparatorFunc func(string) string) (*Handlers, error) {
if userdataStore == nil {
return nil, fmt.Errorf("cannot create handler with nil userdata store")
}
userDb := &common.UserDataStore{
Db: userdataStore,
}
// Instantiate the SubPrefixDb with "DATATYPE_USERDATA" prefix
prefix := common.ToBytes(db.DATATYPE_USERDATA)
prefixDb := dbstorage.NewSubPrefixDb(userdataStore, prefix)
h := &Handlers{
userdataStore: userDb,
flagManager: appFlags,
adminstore: adminstore,
accountService: accountService,
prefixDb: prefixDb,
profile: &models.Profile{Max: 6},
ReplaceSeparatorFunc: replaceSeparatorFunc,
}
return h, nil
}
func (h *Handlers) Exit() {
h.pe = nil
}
func (h *Handlers) Init(ctx context.Context, sym string, input []byte) (resource.Result, error) {
return resource.Result{}, nil
}
// WithPersister sets persister instance to the handlers.
func (h *Handlers) WithPersister(pe *persist.Persister) *Handlers {
if h.pe != nil {
panic("persister already set")
}
h.pe = pe
return h
}
type BaseSessionHandler struct {
cfgTemplate engine.Config
2025-01-04 23:27:46 +01:00
rp request.RequestParser
rs resource.Resource
2025-01-10 13:03:37 +01:00
hn *Handlers
provider storage.StorageProvider
}
2025-01-10 15:04:23 +01:00
func NewBaseSessionHandler(cfg engine.Config, rs resource.Resource, stateDb db.Db, userdataDb db.Db, rp request.RequestParser, hn *Handlers) *BaseSessionHandler {
return &BaseSessionHandler{
cfgTemplate: cfg,
rs: rs,
hn: hn,
rp: rp,
provider: storage.NewSimpleStorageProvider(stateDb, userdataDb),
}
}
func (f *BaseSessionHandler) Shutdown() {
err := f.provider.Close()
if err != nil {
logg.Errorf("handler shutdown error", "err", err)
}
}
func (f *BaseSessionHandler) GetEngine(cfg engine.Config, rs resource.Resource, pr *persist.Persister) engine.Engine {
en := engine.NewEngine(cfg, rs)
en = en.WithPersister(pr)
return en
}
2025-01-04 23:27:46 +01:00
func(f *BaseSessionHandler) Process(rqs request.RequestSession) (request.RequestSession, error) {
var r bool
var err error
var ok bool
2024-09-23 18:35:17 +02:00
logg.InfoCtxf(rqs.Ctx, "new request", "data", rqs)
rqs.Storage, err = f.provider.Get(rqs.Config.SessionId)
if err != nil {
logg.ErrorCtxf(rqs.Ctx, "", "storage get error", err)
2025-01-05 12:17:58 +01:00
return rqs, errors.ErrStorage
}
f.hn = f.hn.WithPersister(rqs.Storage.Persister)
defer func() {
f.hn.Exit()
}()
eni := f.GetEngine(rqs.Config, f.rs, rqs.Storage.Persister)
en, ok := eni.(*engine.DefaultEngine)
if !ok {
perr := f.provider.Put(rqs.Config.SessionId, rqs.Storage)
rqs.Storage = nil
if perr != nil {
logg.ErrorCtxf(rqs.Ctx, "", "storage put error", perr)
}
2025-01-05 12:17:58 +01:00
return rqs, errors.ErrEngineType
}
en = en.WithFirst(f.hn.Init)
if rqs.Config.EngineDebug {
en = en.WithDebug(nil)
}
rqs.Engine = en
2024-09-20 12:13:20 +02:00
r, err = rqs.Engine.Exec(rqs.Ctx, rqs.Input)
if err != nil {
perr := f.provider.Put(rqs.Config.SessionId, rqs.Storage)
rqs.Storage = nil
if perr != nil {
logg.ErrorCtxf(rqs.Ctx, "", "storage put error", perr)
}
return rqs, err
}
rqs.Continue = r
return rqs, nil
}
2025-01-04 23:27:46 +01:00
func(f *BaseSessionHandler) Output(rqs request.RequestSession) (request.RequestSession, error) {
var err error
2024-09-20 21:15:24 +02:00
_, err = rqs.Engine.Flush(rqs.Ctx, rqs.Writer)
return rqs, err
}
2025-01-04 23:27:46 +01:00
func(f *BaseSessionHandler) Reset(rqs request.RequestSession) (request.RequestSession, error) {
defer f.provider.Put(rqs.Config.SessionId, rqs.Storage)
return rqs, rqs.Engine.Finish()
}
func (f *BaseSessionHandler) GetConfig() engine.Config {
return f.cfgTemplate
}
2025-01-04 23:27:46 +01:00
func(f *BaseSessionHandler) GetRequestParser() request.RequestParser {
return f.rp
}