feat: state is now scoped by both user id and chat id
This commit is contained in:
1 parent
4b94fcb920
commit
ec12f29fdb
3 files changed
+31
-23
No files matched your search
@@ -19,6 +19,11 @@ type EventIsolation struct {
|
||||
ttl time.Duration
|
||||
}
|
||||
|
||||
type fsmKey struct {
|
||||
userID int64
|
||||
chatID int64
|
||||
}
|
||||
|
||||
type eventIsolationKey struct {
|
||||
userID int
|
||||
chatID int
|
||||
@@ -34,8 +39,11 @@ func NewFSMStorage() *FSMStorage {
|
||||
return &FSMStorage{}
|
||||
}
|
||||
|
||||
func (f *FSMStorage) Get(_ context.Context, userID int) (state.Snapshot, error) {
|
||||
st, ok := f.m.Load(userID)
|
||||
func (f *FSMStorage) Get(_ context.Context, scope isolation.Scope) (state.Snapshot, error) {
|
||||
st, ok := f.m.Load(fsmKey{
|
||||
userID: scope.UserID,
|
||||
chatID: scope.ChatID,
|
||||
})
|
||||
if !ok {
|
||||
return state.Snapshot{}, state.ErrStateNotFound
|
||||
}
|
||||
@@ -44,12 +52,18 @@ func (f *FSMStorage) Get(_ context.Context, userID int) (state.Snapshot, error)
|
||||
}
|
||||
|
||||
func (f *FSMStorage) Put(_ context.Context, snapshot state.Snapshot) error {
|
||||
f.m.Store(snapshot.ID, snapshot)
|
||||
f.m.Store(fsmKey{
|
||||
userID: snapshot.Scope.UserID,
|
||||
chatID: snapshot.Scope.ChatID,
|
||||
}, snapshot)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FSMStorage) Delete(_ context.Context, userID int) error {
|
||||
f.m.Delete(userID)
|
||||
func (f *FSMStorage) Delete(_ context.Context, scope isolation.Scope) error {
|
||||
f.m.Delete(fsmKey{
|
||||
userID: scope.UserID,
|
||||
chatID: scope.ChatID,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
+7
-13
@@ -3,8 +3,7 @@ package state
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/abelith/gomax/v1/isolation"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -32,13 +31,13 @@ func (JSONCodec) Unmarshal(d []byte, v any) error {
|
||||
}
|
||||
|
||||
type Snapshot struct {
|
||||
ID int `json:"id"`
|
||||
Scope isolation.Scope `json:"id"`
|
||||
State State `json:"state"`
|
||||
Data map[string][]byte `json:"data"`
|
||||
}
|
||||
|
||||
type Context struct {
|
||||
id int
|
||||
scope isolation.Scope
|
||||
state State
|
||||
data map[string][]byte
|
||||
codec Codec
|
||||
@@ -48,9 +47,9 @@ type Option func(*Context)
|
||||
|
||||
func WithCodec(c Codec) Option { return func(sc *Context) { sc.codec = c } }
|
||||
|
||||
func New(id int, opts ...Option) *Context {
|
||||
func New(scope isolation.Scope, opts ...Option) *Context {
|
||||
sc := &Context{
|
||||
id: id,
|
||||
scope: scope,
|
||||
data: make(map[string][]byte),
|
||||
codec: JSONCodec{},
|
||||
}
|
||||
@@ -61,7 +60,7 @@ func New(id int, opts ...Option) *Context {
|
||||
}
|
||||
|
||||
func Restore(s Snapshot, opts ...Option) *Context {
|
||||
sc := New(s.ID, opts...)
|
||||
sc := New(s.Scope, opts...)
|
||||
sc.state = s.State
|
||||
for k, v := range s.Data {
|
||||
sc.data[k] = v
|
||||
@@ -74,15 +73,10 @@ func (sc *Context) Snapshot() Snapshot {
|
||||
for k, v := range sc.data {
|
||||
data[k] = v
|
||||
}
|
||||
return Snapshot{ID: sc.id, State: sc.state, Data: data}
|
||||
return Snapshot{Scope: sc.scope, State: sc.state, Data: data}
|
||||
}
|
||||
|
||||
func (sc *Context) Set(state State) {
|
||||
log.Debug().
|
||||
Int("user_id", sc.id).
|
||||
Str("from", string(sc.state)).
|
||||
Str("to", string(state)).
|
||||
Msg("fsm state transition")
|
||||
sc.state = state
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user