Go言語で、Actorっぽいことができないか試してみました。Go Playgroundで動作するサンプルを試せます。
package main
import (
"log"
"time"
)
func main() {
log.Println("started")
actor := NewActor()
go actor.React()
// send Increment per second
go func() {
for i := 0; i <= 10; i++ {
actor.Increment <- &Increment{}
time.Sleep(1 * time.Second)
}
}()
// send Decrement per two seconds
go func() {
for i := 0; i <= 10; i++ {
actor.Decrement <- &Decrement{}
time.Sleep(2 * time.Second)
}
}()
// send Stop in seven seconds
go func() {
time.Sleep(7 * time.Second)
actor.Stop <- &Stop{}
}()
// send Letter per two seconds
go func() {
messages := []string{"hi!", "yo!"}
for _, msg := range messages {
time.Sleep(2 * time.Second)
actor.Letter <- &Letter{msg}
}
}()
// wait for all messages are sent.
time.Sleep(10 * time.Second)
log.Println("finished")
}
type Increment struct {
}
type Decrement struct {
}
type Stop struct {
}
type Letter struct {
Body string
}
type Actor struct {
number int
Increment chan *Increment
Decrement chan *Decrement
Letter chan *Letter
Stop chan *Stop
}
func NewActor() *Actor {
return &Actor{
number: 0,
Increment: make(chan *Increment),
Decrement: make(chan *Decrement),
Letter: make(chan *Letter),
Stop: make(chan *Stop),
}
}
func (a *Actor) React() {
for {
select {
case <-a.Increment:
a.number += 1
log.Printf("incremented: %d", a.number)
case <-a.Decrement:
a.number -= 1
log.Printf("decremented: %d", a.number)
case letter := <-a.Letter:
log.Printf("letter recieved: %s", letter.Body)
case <-a.Stop:
log.Println("stopping")
return
}
}
}
実行結果
2009/11/10 23:00:00 started
2009/11/10 23:00:00 incremented: 1
2009/11/10 23:00:00 decremented: 0
2009/11/10 23:00:01 incremented: 1
2009/11/10 23:00:02 decremented: 0
2009/11/10 23:00:02 letter recieved: hi!
2009/11/10 23:00:02 incremented: 1
2009/11/10 23:00:03 incremented: 2
2009/11/10 23:00:04 decremented: 1
2009/11/10 23:00:04 incremented: 2
2009/11/10 23:00:04 letter recieved: yo!
2009/11/10 23:00:05 incremented: 3
2009/11/10 23:00:06 decremented: 2
2009/11/10 23:00:06 incremented: 3
2009/11/10 23:00:07 stopping
2009/11/10 23:00:10 finished