graphql-engine/cli/internal/fsm/fsm.go
hasura-bot 20f7c85382 cli: add deploy command (close #7349)
GITHUB_PR_NUMBER: 7426
GITHUB_PR_URL: https://github.com/hasura/graphql-engine/pull/7426

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/2173
Co-authored-by: Ajay Tripathi <24985760+atb00ker@users.noreply.github.com>
Co-authored-by: Kali Vara Purushotham Santhati <72007599+purush7@users.noreply.github.com>
Co-authored-by: Aravind K P <8335904+scriptonist@users.noreply.github.com>
GitOrigin-RevId: 1030d24c9e6c7d0c7062b6f0e98f8464950529d3
2021-09-29 06:15:17 +00:00

75 lines
1.3 KiB
Go

package fsm
import (
"fmt"
"sync"
"github.com/pkg/errors"
)
var ErrEventRejected = errors.New("event rejected")
const (
Default StateType = ""
NoOp EventType = "NoOp"
)
type StateType string
type EventType string
type EventContext interface{}
type Action interface {
Execute(eventCtx EventContext) EventType
}
type Events map[EventType]StateType
type State struct {
Action Action
Events Events
}
type States map[StateType]State
type StateMachine struct {
Previous StateType
Current StateType
States States
mutex sync.Mutex
}
func (s *StateMachine) getNextState(event EventType) (StateType, error) {
if state, ok := s.States[s.Current]; ok {
if state.Events != nil {
if next, ok := state.Events[event]; ok {
return next, nil
}
}
}
return Default, fmt.Errorf("next state: %w: %s", ErrEventRejected, event)
}
func (s *StateMachine) SendEvent(event EventType, eventCtx EventContext) error {
s.mutex.Lock()
defer s.mutex.Unlock()
for {
nextState, err := s.getNextState(event)
if err != nil {
return fmt.Errorf("%w: %s", err, event)
}
state, ok := s.States[nextState]
if !ok || state.Action == nil {
return fmt.Errorf("config error")
}
s.Previous = s.Current
s.Current = nextState
nextEvent := state.Action.Execute(eventCtx)
if nextEvent == NoOp {
return nil
}
event = nextEvent
}
}