package handlers import ( "context" "fmt" "git.defalsify.org/vise.git/asm" "git.defalsify.org/vise.git/db" "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" "git.defalsify.org/vise.git/logging" "git.grassecon.net/grassrootseconomics/visedriver/request" "git.grassecon.net/grassrootseconomics/visedriver/errors" dbstorage "git.grassecon.net/grassrootseconomics/visedriver/storage/db" "git.grassecon.net/grassrootseconomics/visedriver/common" "git.grassecon.net/grassrootseconomics/visedriver/storage" "git.grassecon.net/grassrootseconomics/visedriver/remote" "git.grassecon.net/grassrootseconomics/visedriver/models" "git.grassecon.net/grassrootseconomics/visedriver/utils" ) var ( logg = logging.NewVanilla().WithDomain("handlers") ) 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 } // 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 rp request.RequestParser rs resource.Resource hn *Handlers provider storage.StorageProvider } 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 } func(f *BaseSessionHandler) Process(rqs request.RequestSession) (request.RequestSession, error) { var r bool var err error var ok bool 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) 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) } return rqs, errors.ErrEngineType } en = en.WithFirst(f.hn.Init) if rqs.Config.EngineDebug { en = en.WithDebug(nil) } rqs.Engine = en 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 } func(f *BaseSessionHandler) Output(rqs request.RequestSession) (request.RequestSession, error) { var err error _, err = rqs.Engine.Flush(rqs.Ctx, rqs.Writer) return rqs, err } 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 } func(f *BaseSessionHandler) GetRequestParser() request.RequestParser { return f.rp }