package uniss import ( "context" "dashboard/pkg/fsm" "time" "git.zhangshuocauc.cn/redhat/timewheel" "go.uber.org/zap" ) const ( unisFsmEventReset fsm.EventName = "unisFsmEventReset" unisFsmEventOfline fsm.EventName = "unisFsmEventOfline" unisFsmEventOnline fsm.EventName = "unisFsmEventOnline" unisFsmEventLoginId fsm.EventName = "unisFsmEventLoginId" unisFsmEventLoginSync fsm.EventName = "unisFsmEventLoginSync" unisFsmEventLoginForce fsm.EventName = "unisFsmEventLoginForce" unisFsmEventLoginServer fsm.EventName = "unisFsmEventLoginServer" unisFsmEventLogout fsm.EventName = "unisFsmEventLogout" unisFsmEventLogoutForce fsm.EventName = "unisFsmEventLogoutForce" unisFsmEventLogoutServer fsm.EventName = "unisFsmEventLogoutServer" unisFsmEventLogin fsm.EventName = "unisFsmEventLogin" unisFsmEventLoginSyncFailed fsm.EventName = "unisFsmEventLoginSyncFailed" unisFsmEventLoginSyncSuccess fsm.EventName = "unisFsmEventLoginSyncSuccess" unisFsmEventLoginSuccess fsm.EventName = "unisFsmEventLoginSuccess" unisFsmEventLoginFailed fsm.EventName = "unisFsmEventLoginFailed" unisFsmEventLogoutSuccess fsm.EventName = "unisFsmEventLogoutSuccess" unisFsmEventLogoutFailed fsm.EventName = "unisFsmEventLogoutFailed" ) var events = fsm.Events{ unisFsmEventReset, unisFsmEventLoginSuccess, unisFsmEventLoginFailed, unisFsmEventLogoutSuccess, unisFsmEventLogoutFailed, } type fsmService struct { unisMSystemFsm *unisMSystemFsm unisMStateFsm *unisMStateFsm } func (f *fsmService) reset(ctx context.Context) { f.unisMSystemFsm.reset(ctx) f.unisMStateFsm.reset(ctx) } func newfsmService() (fsm *fsmService, err error) { fsm = &fsmService{} fsm.unisMSystemFsm, err = newunisMSystemFsm() if err != nil { return } fsm.unisMStateFsm, err = newunisMStateFsm() if err != nil { return } return } /*******************************主逻辑在线离线状态机************************************/ type unisMSystemFsm struct { fsm *fsm.FSM } const ( unisMSystem = "unisMSystem" unisMIdle = "unisMIdle" unisMOnLine = "unisMOnLine" unisMOfLine = "unisMOfLine" unisMOnLineIdle = "unisMOnLineIdle" unisMOnLineLoginId = "unisMOnLineLoginId" unisMOnLineLoginning = "unisMOnLineLoginning" unisMOnLineLogouting = "unisMOnLineLogouting" unisMOnLineLoginSync = "unisMOnLineLoginSync" ) func newunisMSystemFsm() (*unisMSystemFsm, error) { res := new(unisMSystemFsm) fsm, err := fsm.NewFsm(unisMSystem, unisMIdle, events, []*fsm.StateRule{ {Name: unisMSystem, Parent: "", InitState: unisMIdle, Processor: res.unisMSystem, Dst: []string{}}, {Name: unisMIdle, Parent: unisMSystem, InitState: "", Processor: res.unisMIdle, Dst: []string{}}, {Name: unisMOnLine, Parent: unisMSystem, InitState: unisMOnLineIdle, Processor: res.unisMOnLine, Dst: []string{}}, {Name: unisMOfLine, Parent: unisMSystem, InitState: "", Processor: res.unisMOfLine, Dst: []string{}}, {Name: unisMOnLineIdle, Parent: unisMOnLine, InitState: "", Processor: res.unisMOnLineIdle, Dst: []string{}}, {Name: unisMOnLineLoginId, Parent: unisMOnLine, InitState: "", Processor: res.unisMOnLineLoginId, Dst: []string{}}, {Name: unisMOnLineLoginning, Parent: unisMOnLine, InitState: "", Processor: res.unisMOnLineLoginning, Dst: []string{}}, {Name: unisMOnLineLogouting, Parent: unisMOnLine, InitState: "", Processor: res.unisMOnLineLogouting, Dst: []string{}}, {Name: unisMOnLineLoginSync, Parent: unisMOnLine, InitState: "", Processor: res.unisMOnLineLoginSync, Dst: []string{}}, }, zap.NewStdLog(log.Logger)) if err != nil { log.Sugar().Error(err) return nil, err } res.fsm = fsm return res, nil } func (f *unisMSystemFsm) reset(ctx context.Context) { f.fsm.ExecuteEvent(ctx, unisFsmEventReset, nil) } func (f *unisMSystemFsm) unisMSystem(ctx context.Context, e *fsm.Event) error { switch e.Event { case fsm.EventEntry: case fsm.EventExit: case unisFsmEventReset: e.FSM.StateChange(ctx, unisMIdle, nil) default: return fsm.EventNoProc } return fsm.EventOK } func (f *unisMSystemFsm) unisMIdle(ctx context.Context, e *fsm.Event) error { switch e.Event { case fsm.EventEntry: case fsm.EventExit: case unisFsmEventOfline: e.FSM.StateChange(ctx, unisMOfLine, nil) case unisFsmEventOnline: e.FSM.StateChange(ctx, unisMOnLineLoginSync, nil) default: return fsm.EventNoProc } return fsm.EventOK } func (f *unisMSystemFsm) unisMOnLine(ctx context.Context, e *fsm.Event) error { switch e.Event { case fsm.EventEntry: case fsm.EventExit: case unisFsmEventOfline: e.FSM.StateChange(ctx, unisMOfLine, nil) case unisFsmEventLoginId: case unisFsmEventLoginSync: e.FSM.StateChange(ctx, unisMOnLineLoginSync, nil) default: return fsm.EventNoProc } return fsm.EventOK } func (f *unisMSystemFsm) unisMOfLine(ctx context.Context, e *fsm.Event) error { switch e.Event { case fsm.EventEntry: case fsm.EventExit: case unisFsmEventOnline: e.FSM.StateChange(ctx, unisMOnLineLoginSync, nil) default: return fsm.EventNoProc } return fsm.EventOK } /**********************************主逻辑登录状态机***********************************/ func (f *unisMSystemFsm) unisMOnLineIdle(ctx context.Context, e *fsm.Event) error { switch e.Event { case fsm.EventEntry: case fsm.EventExit: case unisFsmEventLoginId: e.FSM.StateChange(ctx, unisMOnLineLoginId, e.Args) case unisFsmEventLoginForce: e.FSM.StateChange(ctx, unisMOnLineLoginning, e.Args) case unisFsmEventLoginServer: case unisFsmEventLogout: e.FSM.StateChange(ctx, unisMOnLineLogouting, e.Args) case unisFsmEventLogoutForce: fallthrough case unisFsmEventLogoutServer: default: return fsm.EventNoProc } return fsm.EventOK } func (f *unisMSystemFsm) unisMOnLineLoginId(ctx context.Context, e *fsm.Event) error { switch e.Event { case fsm.EventEntry: e.FSM.StartEventTimer(ctx, timewheel.TimerTypeOnce, time.Second*5, nil) case fsm.EventExit: e.FSM.StopEventTimer() case unisFsmEventLogin: e.FSM.StateChange(ctx, unisMOnLineLoginning, e.Args) case fsm.EventTimeOut: e.FSM.StateChange(ctx, unisMOnLineIdle, nil) case unisFsmEventLoginFailed: e.FSM.StateChange(ctx, unisMOnLineIdle, nil) default: return fsm.EventNoProc } return fsm.EventOK } func (f *unisMSystemFsm) unisMOnLineLoginning(ctx context.Context, e *fsm.Event) error { switch e.Event { case fsm.EventEntry: e.FSM.StartEventTimer(ctx, timewheel.TimerTypeOnce, time.Second*5, nil) case fsm.EventExit: e.FSM.StopEventTimer() case fsm.EventTimeOut: e.FSM.StateChange(ctx, unisMOnLineIdle, nil) case unisFsmEventLoginFailed: e.FSM.StateChange(ctx, unisMOnLineIdle, nil) case unisFsmEventLoginSuccess: e.FSM.StateChange(ctx, unisMOnLineIdle, nil) default: return fsm.EventNoProc } return fsm.EventOK } func (f *unisMSystemFsm) unisMOnLineLogouting(ctx context.Context, e *fsm.Event) error { switch e.Event { case fsm.EventEntry: e.FSM.StartEventTimer(ctx, timewheel.TimerTypeOnce, time.Second*5, nil) case fsm.EventExit: e.FSM.StopEventTimer() case fsm.EventTimeOut: fallthrough case unisFsmEventLogoutFailed: fallthrough case unisFsmEventLogoutSuccess: e.FSM.StateChange(ctx, unisMOnLineIdle, nil) default: return fsm.EventNoProc } return fsm.EventOK } func (f *unisMSystemFsm) unisMOnLineLoginSync(ctx context.Context, e *fsm.Event) error { switch e.Event { case fsm.EventEntry: e.FSM.StartEventTimer(ctx, timewheel.TimerTypeOnce, time.Second*10, nil) case fsm.EventExit: e.FSM.StopEventTimer() case fsm.EventTimeOut: case unisFsmEventLoginSyncFailed: case unisFsmEventLoginSyncSuccess: default: return fsm.EventNoProc } return fsm.EventOK } /***************************主登录状态机********************************************/ type unisMStateFsm struct { fsm *fsm.FSM } const ( unisMState = "unisMState" unisMStateIdle = "unisMStateIdle" unisMStateLogin = "unisMStateLogin" unisMStateLogout = "unisMStateLogout" ) func newunisMStateFsm() (*unisMStateFsm, error) { res := new(unisMStateFsm) fsm, err := fsm.NewFsm(unisMState, unisMState, events, []*fsm.StateRule{ {Name: unisMState, Parent: "", InitState: unisMStateIdle, Processor: res.unisMState, Dst: []string{}}, {Name: unisMStateIdle, Parent: unisMState, InitState: "", Processor: res.unisMStateIdle, Dst: []string{}}, {Name: unisMStateLogin, Parent: unisMState, InitState: "", Processor: res.unisMStateLogin, Dst: []string{}}, {Name: unisMStateLogout, Parent: unisMState, InitState: "", Processor: res.unisMStateLogout, Dst: []string{}}, {}, }, zap.NewStdLog(log.Logger)) if err != nil { log.Sugar().Error(err) return nil, err } res.fsm = fsm return res, nil } func (f *unisMStateFsm) reset(ctx context.Context) { f.fsm.ExecuteEvent(ctx, unisFsmEventReset, nil) } func (f *unisMStateFsm) unisMState(ctx context.Context, e *fsm.Event) error { switch e.Event { case fsm.EventEntry: case fsm.EventExit: case unisFsmEventReset: e.FSM.StateChange(ctx, unisMStateIdle, nil) case unisFsmEventLoginFailed: case unisFsmEventLogoutFailed: e.FSM.StateChange(ctx, unisMStateLogout, nil) default: return fsm.EventNoProc } return fsm.EventOK } func (f *unisMStateFsm) unisMStateIdle(ctx context.Context, e *fsm.Event) error { switch e.Event { case fsm.EventEntry: case fsm.EventExit: case unisFsmEventLoginSuccess: e.FSM.StateChange(ctx, unisMStateLogin, e.Args) case unisFsmEventLogoutSuccess: e.FSM.StateChange(ctx, unisMStateLogout, e.Args) default: return fsm.EventNoProc } return fsm.EventOK } func (f *unisMStateFsm) unisMStateLogin(ctx context.Context, e *fsm.Event) error { switch e.Event { case fsm.EventEntry: e.FSM.StartEventTimer(ctx, timewheel.TimerTypeOnce, time.Minute*5, nil) case fsm.EventExit: e.FSM.StopEventTimer() case fsm.EventTimeOut: e.FSM.StartEventTimer(ctx, timewheel.TimerTypeOnce, time.Minute*5, nil) case unisFsmEventLoginSuccess: case unisFsmEventLogoutSuccess: e.FSM.StateChange(ctx, unisMStateLogout, e.Args) default: return fsm.EventNoProc } return fsm.EventOK } func (f *unisMStateFsm) unisMStateLogout(ctx context.Context, e *fsm.Event) error { switch e.Event { case fsm.EventEntry: case fsm.EventExit: case unisFsmEventLoginSuccess: e.FSM.StateChange(ctx, unisMStateLogin, e.Args) default: return fsm.EventNoProc } return fsm.EventOK }