Amparo
Amparo

Reputation: 824

State machine in Go

I have a kind of state machine. So I have states:

const (
    state1 = iota
    state2
    state3
    exit
)

Also, I have a chan:

stateMachine := make(chan int)

I put the first state:

stateMachine <- state1

And then, I enter in infinite loop like this:

for {
   select {
   case state := <- stateMachine:
      switch state {
      case state1: 
         fmt.Println("state1")
         stateMachine <- state2
      case state2: 
         fmt.Println("state2")
         stateMachine <- state3
      case state3: 
         fmt.Println("state3")
         stateMachine <- exit
      case exit:
         fmt.Println("Exit")
         os.Exit(0)
      }
   }
}

But it does not work.

https://play.golang.org/p/s5uYJy-fMKe

Upvotes: 0

Views: 1053

Answers (2)

Amparo
Amparo

Reputation: 824

I do not know why but this works:

package main

import (
    "fmt"
    "os"
)

const (
    state1 = iota
    state2
    state3
    exit
)

func main() {
    stateMachine := make(chan int)
    go func() { stateMachine <- state1 }()
    for {
        select {
        case state := <-stateMachine:
            switch state {
            case state1:
                fmt.Println("state1")
                go func() { stateMachine <- state2 }()
            case state2:
                fmt.Println("state2")
                go func() { stateMachine <- state3 }()
            case state3:
                fmt.Println("state3")
                go func() { stateMachine <- exit }()
            case exit:
                fmt.Println("Exit")
                os.Exit(0)
            }
        }
    }
}

https://play.golang.org/p/JH-w6SDCh-Z

Upvotes: -1

Burak Serdar
Burak Serdar

Reputation: 51632

A channel is a synchronization mechanism. A write or read to an unbuffered channel will succeed only if there is another goroutine waiting to read/write from that same channel. Since you have an unbuffered channel and attempting to use channel as state storage, your first write blocks because there is no other goroutine reading from it.

Try with a channel with capacity 1:

stateMachine := make(chan int,1)

That will let writes work as long as the channel has storage.

Upvotes: 3

Related Questions