fsml

package module
v0.1.0-alpha Latest Latest
Warning

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

Go to latest
Published: Apr 9, 2021 License: Apache-2.0 Imports: 7 Imported by: 0

README

fsml Bulid Status Coverage Status Go Report Card

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. Here is an example of state machine definition in xml format.

<Schema>
    <States>
        <new>
            <Events>
                <DummyEvent targetState="pending" errorState="error"></DummyEvent>
            </Events>
        </new>
        <pending></pending>
        <error></error>
    </States>
</Schema>

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.

 <Schema>
    <OnStateSet></OnStateSet>
    <States>
        <new>
            <OnStateSet></OnStateSet>
            <Events>
                <DummyEvent targetState="pending" errorState="error"></DummyEvent>
            </Events>
        </new>
        <pending></pending>
        <error></error>
    </States>
</Schema>
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

    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{})
    <new>
        <OnStateSet></OnStateSet>
        <Events>
            <DummyEvent targetState="pending" errorState="error">
                <Task>increment</Task>
                <Task>increment</Task>
            </DummyEvent>
        </Events>
    </new>


Code Example examples/basic.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
    // 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 `<Schema>
                <States>
                    <new>
                        <Events>
                            <DummyEvent targetState="pending" errorState="error"></DummyEvent>
                        </Events>
                    </new>
                    <pending></pending>
                    <error></error>
                </States>
            </Schema>`
    }

License

FSML is licensed under Apache License 2.0

http://www.apache.org/licenses/LICENSE-2.0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Stateful

type Stateful interface {
	GetState() string
	SetState(state string) error
}

Stateful ...

type Statemachine

type Statemachine struct {
	// contains filtered or unexported fields
}

Statemachine ...

func New

func New(input io.Reader) (*Statemachine, error)

New ...

func (*Statemachine) AddTask

func (s *Statemachine) AddTask(task Task) error

AddTask ...

func (*Statemachine) Can

func (s *Statemachine) Can(eventName string, entity interface{}) bool

Can ...

func (*Statemachine) RemoveTask

func (s *Statemachine) RemoveTask(task Task) error

RemoveTask ...

func (*Statemachine) Trigger

func (s *Statemachine) Trigger(eventName string, entity interface{}) error

Trigger ...

type Task

type Task interface {
	Name() string
	Execute(entity interface{}) error
}

Task ...

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

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