// Actor model (state machine)
type stateMachine struct {
state string
actionc chan func ()
}
func newStateMachine () * stateMachine {
return & stateMachine {
state : "initial" ,
actionc : make (chan func ()),
}
}
func (sm * stateMachine ) Run (ctx context.Context ) error {
for {
select {
case f := <- sm .actionc :
f ()
case <- ctx .Done ():
return ctx .Err ()
}
}
}
func (sm * stateMachine ) foo () int {
c := make (chan int )
sm .actionc <- func () {
// Do some stuff inside
sm .state = "processing foo"
c <- 123
}
return <- c
}
Orchestrating actors (using group )
var g group.Group
{
ctx , cancel := context .WithCancel (context .Background ())
g .Add (func () error {
return sm .Run (ctx )
}, func (error ) {
cancel ()
})
}
// Considering server as an actor too
{
ln , _ := net .Listen ("tcp" , ":8080" )
g .Add (func () error {
return http .Serve (ln , api )
}, func (error ) {
ln .Close ()
})
}
// Other stuff too
{
cancel := make (chan struct {})
g .Add (func () error {
return cronJobs (cancel , sm )
}, func (error ) {
close (cancel )
}
}
g .Run ()