https://github.com/zain-bahsarat/fsml
XML based finite statemachine in GO
https://github.com/zain-bahsarat/fsml
finite-state-machine fsm go golang statemachine xml xml-schema
Last synced: 6 months ago
JSON representation
XML based finite statemachine in GO
- Host: GitHub
- URL: https://github.com/zain-bahsarat/fsml
- Owner: zain-bahsarat
- License: apache-2.0
- Created: 2021-04-08T22:10:05.000Z (about 5 years ago)
- Default Branch: main
- Last Pushed: 2021-04-13T20:31:32.000Z (about 5 years ago)
- Last Synced: 2024-06-20T06:30:48.073Z (about 2 years ago)
- Topics: finite-state-machine, fsm, go, golang, statemachine, xml, xml-schema
- Language: Go
- Homepage:
- Size: 33.2 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: Readme.md
- License: LICENSE
Awesome Lists containing this project
README
# fsml  [](https://coveralls.io/r/zain-bahsarat/fsml) [](https://goreportcard.com/report/zain-bahsarat/fsml)
**FSML** is a XML based wrapper on top of https://github.com/looplab/fsm.
It provides the capabilities to define state machine of an entity in XML format and also supports features to handle error states and tasks execution on events and successful transition.
## Installation
```shell
$ go get github.com/zain-bahsarat/fsml
```
## Usage
```go
import (
"fmt"
"strings"
"github.com/zain-bahsarat/fsml"
)
// Every object which is passed to the statemachine has to implement
// `Stateful` interface otherwise it will throw error
// -------------------------------------
// type Stateful interface{
// GetState() string
// SetState(state string) error
// }
// -------------------------------------
// create an entity which implements stateful interface
type order struct {
state string
fsml.Stateful
}
func (o *order) SetState(state string) error {
o.state = state
return nil
}
func (o *order) GetState() string {
return o.state
}
func main() {
statemachineDef := getSimpleStatemachineDef()
reader := strings.NewReader(statemachineDef)
sm, err := fsml.New(reader)
if err != nil {
fmt.Printf("error= %+v\n", sm)
}
o := &order{}
o.SetState("new")
if err := sm.Trigger("DummyEvent", o); err != nil {
fmt.Printf("error= %+v\n", err)
}
if !sm.Can("UndefinedEvent", o) {
fmt.Printf("cannot trigger UndefinedEvent on %+v\n", o)
}
}
// state machine definition
func getSimpleStatemachineDef() string {
return `
`
}
```
Here is an example of state machine definition in xml format.
```xml
```
Above statemachine has three states `new`, `pending` and `error` and event named `DummyEvent`
## Schema Definition
### Nodes
- Schema `Root Node`
- States `Container Node`
- All the state definitions will be inside this node
- Events `Container Node`
- Task
- OnStateSet `Default Event`
- OnAfterEvent `Default Event`
- OnBeforeEvent `Default Event`
### Default Events
Default events can used inside each state to define default behaviors when state is updated. you can also define global default events.
```xml
```
### Custom Events
Custom events can be deined inside `Events` Node. There is an option to define `targetState`(required) and `errorState` which will take effect based on transition result
### Tasks
`Task` Node is defined inside Custom Event or Default Event when we want to execute some task on them. If all tasks defined inside event are executed successfully then state will be changed to `targetState` otherwise it will be `errorState`
Every task needs to implement `fsml.Task` interface to be accessible by statemachine. check `examples/tasks.go`
```go
type task struct {}
func (t *task) Name() string {
return "increment"
}
func (t *task) Execute(i interface{}) error {
entity := i.(*item)
entity.count++
return nil
}
......
statemachine.AddTask(&task{})
```
```xml
increment
increment
```
---
# License
FSML is licensed under Apache License 2.0
http://www.apache.org/licenses/LICENSE-2.0