gofsm

package module
v0.0.0-...-42b1f81 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 12, 2020 License: MIT Imports: 7 Imported by: 0

README

gofsm

Build Status codecov

一个简单、高效的有限状态机执行框架

使用

例如 电商网站中的 订单状态(这里做了简化)

  • 新建状态机
import "github.com/threeq/gofsm"

// 订单状态定义
const (
    Start       = "Start"
    WaitPay     = "WaitPay"
    Paying      = "Paying"
    WaitSend    = "WaitSend"
    Sending     = "Sending"
    WaitConfirm = "WaitConfirm"
    Received    = "Received"
    PayFailure  = "PayFailure"
    Canceled    = "Canceled"
)

// 订单时间定义
const (
    CreateEvent          = "Create"
    PayEvent             = "Pay"
    PaySuccessEvent      = "PaySuccess"
    PayFailureEvent      = "PayFailure"
    SendStartEvent       = "SendStart"
    SendEndEvent         = "SendEnd"
    ConfirmReceivedEvent = "SendConfirm"
    CancelEvent          = "Cancel"
)

doAction := func(ctx context.Context, from gofsm.State, event gofsm.Event, to []gofsm.State) (state gofsm.State, e error) {
    println(fmt.Sprintf("doAction: [%v] --%s--> %v", ctx.Value("data"), event, to))
    return to[0], nil
}

orderStateMachine := gofsm.New("myStateMachine").
    States(gofsm.StatesDef{
        Start:       "开始",
        WaitPay:     "待支付",
        Paying:      "支付中",
        WaitSend:    "待发货",
        Sending:     "运输中",
        WaitConfirm: "已收货",
        Received:    "已收货",
        PayFailure:  "支付失败",
        Canceled:    "已取消",
    }).
    Start([]gofsm.State{Start}).
    End([]gofsm.State{Received, Canceled}).
    Events(gofsm.EventsDef{
        CreateEvent:          "创建订单",
        PayEvent:             "支付",
        PaySuccessEvent:      "支付成功",
        PayFailureEvent:      "支付失败",
        SendStartEvent:       "发货",
        SendEndEvent:         "送达",
        ConfirmReceivedEvent: "确认收货",
        CancelEvent:          "去掉订单",
    }).
    Transitions([]gofsm.Transition{
        {Start, CreateEvent, []gofsm.State{WaitPay}, doAction, nil},
        {WaitPay, PayEvent, []gofsm.State{Paying}, doAction, nil},
        {WaitPay, CancelEvent, []gofsm.State{Canceled}, doAction, nil},
        {Paying, PaySuccessEvent, []gofsm.State{WaitSend}, doAction, nil},
        {Paying, PayFailureEvent, []gofsm.State{PayFailure}, doAction, nil},
        {PayFailure, PayEvent, []gofsm.State{Paying}, doAction, nil},
        {PayFailure, CancelEvent, []gofsm.State{Canceled}, doAction, nil},
        {WaitSend, SendStartEvent, []gofsm.State{Sending}, doAction, nil},
        {Sending, SendEndEvent, []gofsm.State{WaitConfirm}, doAction, nil},
        {WaitConfirm, ConfirmReceivedEvent, []gofsm.State{Received}, doAction, nil},
    }...)

println(orderStateMachine.Show())

  • 增加全局状态转换事件监听

这里也可以为每个事件转换单独设置事件监听

type OrderEventProcessor struct{}

func (*OrderEventProcessor) OnExit(ctx context.Context, state gofsm.State, event gofsm.Event) error {
	println(fmt.Sprintf("OnExit: [%v] Exit [%v] on event [%v]", ctx.Value("data"), state, event))
	return nil
}

func (*OrderEventProcessor) OnActionFailure(ctx context.Context, from gofsm.State, event gofsm.Event, to []gofsm.State, err error) error {
	println(fmt.Sprintf("OnActionFailure: [%v] do action error %v --%v--> %v", ctx.Value("data"), from, event, to))
	return nil
}

func (*OrderEventProcessor) OnEnter(ctx context.Context, state gofsm.State) error {
	println(fmt.Sprintf("OnEnter: [%v] Enter [%v]", ctx.Value("data"), state))
	return nil
}

orderStateMachine.Processor(&OrderEventProcessor{})

  • 调用状态机,执行业务操作
order := context.WithValue(context.TODO(), "data", "order object data")
state, err := orderStateMachine.Trigger(order, Start, CreateEvent)
println(fmt.Sprintf("====: %v : %v", state, err))

state, err = orderStateMachine.Trigger(order, Start, PayEvent)
println(fmt.Sprintf("====: %v : %v", state, err))

state, err = orderStateMachine.Trigger(order, Paying, PayFailureEvent)
println(fmt.Sprintf("====: %v : %v", state, err))

output:

OnExit: [order object data] Exit [Start] on event [Create]
doAction: [order object data] --Create--> [WaitPay]
OnEnter: [order object data] Enter [WaitPay]
====: WaitPay : <nil>
====:  : 没有定义状态转换事件 [Start --Pay--> ???]
OnExit: [order object data] Exit [Paying] on event [PayFailure]
doAction: [order object data] --PayFailure--> [PayFailure]
OnEnter: [order object data] Enter [PayFailure]
====: PayFailure : <nil>

完整代码查看 https://github.com/threeq/gofsm/blob/master/fsm_test.goTestStateMachine_Example_Order

Documentation

Index

Constants

View Source
const End = "[*]"
View Source
const None = ""
View Source
const Start = "[*]"

* 默认值定义

Variables

View Source
var NoopProcessor = &DefaultProcessor{}

Functions

func New

func New(name string) *stateMachine

* 创建一个状态机执行器

Types

type Action

type Action func(ctx context.Context, from State, event Event, to []State) (State, error)
var NoopAction Action = func(ctx context.Context, from State, event Event, to []State) (State, error) {
	if to == nil || len(to) == 0 {
		return None, nil
	}
	return to[0], nil
}

type DefaultProcessor

type DefaultProcessor struct{}

* 默认实现

func (*DefaultProcessor) OnActionFailure

func (*DefaultProcessor) OnActionFailure(ctx context.Context, from State, event Event, to []State, err error) error

func (*DefaultProcessor) OnEnter

func (*DefaultProcessor) OnEnter(ctx context.Context, state State) error

func (*DefaultProcessor) OnExit

func (*DefaultProcessor) OnExit(ctx context.Context, state State, event Event) error

type Event

type Event = string

type EventProcessor

type EventProcessor interface {
	OnExit(ctx context.Context, state State, event Event) error
	OnActionFailure(ctx context.Context, from State, event Event, to []State, err error) error
	OnEnter(ctx context.Context, state State) error
}

type EventsDef

type EventsDef map[Event]string

type State

type State = string

type StatesDef

type StatesDef map[State]string

type Transition

type Transition struct {
	From      State
	Event     Event
	To        []State
	Action    Action
	Processor EventProcessor
}

func (Transition) String

func (transfer Transition) String() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL