FSM是finite state machine的缩写,有限状态机是我们在应用开发中经常使用的一种模型,这里简要介绍go语言中https://github.com/looplab/fsm
因为整体比较简单,就直接上代码:
代码业务逻辑简要介绍:
例如一开始是创建状态, 然后是运行状态,运行中是作为这个状态机的初始转台的。
从运行状态可以在更新参数的Event事件触发下进入更新参数状态
可以在增加节点的Event事件触发下进入增加节点状态 可以在增加公网访问地址的Event触发下,进入增加网络地址状态 等等类似这样操作,每种状态自行处理完毕后进入下一个状态,例如更新参数状态处理完毕,进入运行中
package main
import (
"fmt"
"github.com/looplab/fsm"
"k8s.io/klog"
)
const EventRefreshParameter = "refresh_parameter"
const EventAddNode = "add_node"
const EventAddPublicIp = "add_public_ip"
const EventSetRunning = "set_running"
const StateRunning = "running"
const StateRefreshingParameter = "refreshing_parameter"
const StateAddingNode = "adding_node"
const StateAddingPublicIp = "adding_public_ip"
func main() {
fsm := fsm.NewFSM(
StateRunning,
fsm.Events{
{Name: EventRefreshParameter, Src: []string{StateRunning}, Dst: StateRefreshingParameter},
{Name: EventAddNode, Src: []string{StateRunning}, Dst: StateAddingNode},
{Name: EventAddPublicIp, Src: []string{StateRunning}, Dst: StateAddingPublicIp},
{Name: EventSetRunning, Src: []string{StateRefreshingParameter, StateAddingNode, StateAddingPublicIp},
Dst: StateRunning},
},
fsm.Callbacks{ //表示任一的状态或状态事件
"before_event": func(e *fsm.Event) {
klog.Infof("before_event")
},
"leave_state": func(e *fsm.Event) {
klog.Infof("leave_state %q", e.Src)
},
"enter_state": func(e *fsm.Event) {
klog.Infof("enter_state %q -> %q with args:%v", e.Src, e.Dst, e.Args)
},
//根据自定义状态或事件所定义的状态事件函数
"refresh_parameter": func(e *fsm.Event) {
klog.Infof("before_refreshing_parameter, do param refresh action. curr state:%v", e.FSM.Current())
klog.Infof("param refresh action done ,change state to running")
e.FSM.SetState(StateRunning)
},
},
)
klog.Infof("init state %s", fsm.Current())
klog.Infof("send %v event to state %s", EventRefreshParameter, fsm.Current())
err := fsm.Event(EventRefreshParameter, "p1=v1.p2=v2")
if err != nil {
fmt.Println(err)
}
klog.Infof("send %v event to state %s", EventAddNode, fsm.Current())
err = fsm.Event(EventAddNode)
if err != nil {
fmt.Println(err)
}
klog.Infof("send %v event to state %s", EventAddPublicIp, fsm.Current())
err = fsm.Event(EventAddPublicIp)
if err != nil {
fmt.Println(err)
}
klog.Infof("final state %s", fsm.Current())
}
func SetRunning(fsm *fsm.FSM) {
klog.Infof("send %v event to state %s", EventSetRunning, fsm.Current())
err := fsm.Event(EventSetRunning)
if err != nil {
fmt.Println(err)
}
}
运行结果:
I0604 21:34:06.679980 13108 main.go:55] init state running
I0604 21:34:06.679980 13108 main.go:57] send refresh_parameter event to state running
I0604 21:34:06.679980 13108 main.go:33] before_event
I0604 21:34:06.679980 13108 main.go:36] leave_state "running"
I0604 21:34:06.679980 13108 main.go:39] enter_state "running" -> "refreshing_parameter" with args:[p1=v1.p2=v2]
I0604 21:34:06.679980 13108 main.go:46] before_refreshing_parameter, do param refresh action. curr state:refreshing_parameter
I0604 21:34:06.679980 13108 main.go:47] param refresh action done ,change state to running
I0604 21:34:06.679980 13108 main.go:64] send add_node event to state running
I0604 21:34:06.679980 13108 main.go:33] before_event
I0604 21:34:06.679980 13108 main.go:36] leave_state "running"
I0604 21:34:06.679980 13108 main.go:39] enter_state "running" -> "adding_node" with args:[]
I0604 21:34:06.679980 13108 main.go:70] send add_public_ip event to state adding_node
I0604 21:34:06.679980 13108 main.go:76] final state adding_node
event add_public_ip inappropriate in current state adding_node
Process finished with the exit code 0