interact: fix concurrent map write - add mutex on interact

This commit is contained in:
c9s 2023-04-16 21:26:52 +08:00
parent 92b8652f78
commit aa33836fb3
No known key found for this signature in database
GPG Key ID: 7385E7E464CB0A54

View File

@ -3,6 +3,7 @@ package interact
import ( import (
"context" "context"
"fmt" "fmt"
"sync"
"time" "time"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
@ -49,6 +50,8 @@ type Interact struct {
customInteractions []CustomInteraction customInteractions []CustomInteraction
messengers []Messenger messengers []Messenger
mu sync.Mutex
} }
func New() *Interact { func New() *Interact {
@ -63,25 +66,36 @@ func New() *Interact {
func (it *Interact) AddCustomInteraction(custom CustomInteraction) { func (it *Interact) AddCustomInteraction(custom CustomInteraction) {
custom.Commands(it) custom.Commands(it)
it.mu.Lock()
it.customInteractions = append(it.customInteractions, custom) it.customInteractions = append(it.customInteractions, custom)
it.mu.Unlock()
} }
func (it *Interact) PrivateCommand(command, desc string, f interface{}) *Command { func (it *Interact) PrivateCommand(command, desc string, f interface{}) *Command {
cmd := NewCommand(command, desc, f) cmd := NewCommand(command, desc, f)
it.mu.Lock()
it.privateCommands[command] = cmd it.privateCommands[command] = cmd
it.mu.Unlock()
return cmd return cmd
} }
func (it *Interact) Command(command string, desc string, f interface{}) *Command { func (it *Interact) Command(command string, desc string, f interface{}) *Command {
cmd := NewCommand(command, desc, f) cmd := NewCommand(command, desc, f)
it.mu.Lock()
it.commands[command] = cmd it.commands[command] = cmd
it.mu.Unlock()
return cmd return cmd
} }
func (it *Interact) getNextState(session Session, currentState State) (nextState State, final bool) { func (it *Interact) getNextState(session Session, currentState State) (nextState State, final bool) {
var ok bool var ok bool
final = false final = false
it.mu.Lock()
nextState, ok = it.states[currentState] nextState, ok = it.states[currentState]
it.mu.Unlock()
if ok { if ok {
// check if it's the final state // check if it's the final state
if _, hasTransition := it.statesFunc[nextState]; !hasTransition { if _, hasTransition := it.statesFunc[nextState]; !hasTransition {
@ -128,6 +142,9 @@ func (it *Interact) handleResponse(session Session, text string, ctxObjects ...i
} }
func (it *Interact) getCommand(session Session, command string) (*Command, error) { func (it *Interact) getCommand(session Session, command string) (*Command, error) {
it.mu.Lock()
defer it.mu.Unlock()
if session.IsAuthorized() { if session.IsAuthorized() {
if cmd, ok := it.privateCommands[command]; ok { if cmd, ok := it.privateCommands[command]; ok {
return cmd, nil return cmd, nil