patterns/go/statemachine.go

56 lines
1.0 KiB
Go

package main
// Ways To Do Things - Peter Bourgon - Release Party #GoSF
// from https://www.youtube.com/watch?v=LHe1Cb_Ud_M&t=259s
type fooReq struct{}
type barReq struct{}
// really though this should take a context, pass it to loop(),
// and select on ctx.Done()
func NewStateMachine() *stateMachine {
sm := &stateMachine{
state: "initial",
fooc: make(chan fooReq),
barc: make(chan fooReq),
quitc: make(chan chan struct{}),
}
go sm.loop()
return sm
}
type stateMachine struct {
state string
fooc chan fooReq
barc chan barReq
quitc chan struct{}
}
func (sm *stateMachine) foo() int {
c := make(chan int)
sm.fooc <- fooReq{c}
return <-c
}
func (sm *stateMachine) stop() {
q := make(chan struct{})
sm.quitc <- q
// block return until the select in loop() hits
<-q
}
func (sm *stateMachine) loop() {
for {
select {
case r := <-sm.fooc:
sm.handleFoo(r)
case r := <-sm.barc:
sm.handleBar(r)
case: q := <-sm.quitc:
close(q)
return
}
}
}