Skip to content

Instantly share code, notes, and snippets.

@maxsei
Created May 17, 2024 15:47
Show Gist options
  • Save maxsei/c36d5ba0e17f358ebd83d6bd39903ad3 to your computer and use it in GitHub Desktop.
Save maxsei/c36d5ba0e17f358ebd83d6bd39903ad3 to your computer and use it in GitHub Desktop.
basic actor model in golang https://go.dev/play/p/D3RQkzRHcJX
package main
import "log"
type CounterMessage int
func main() {
var a1 *Actor
var a2 *Actor
// Actor 1 pings actor 2 and shuts itself down when count reaches 0.
a1 = NewActor(func(message any) {
log.Printf("actor1: %v", message)
switch v := message.(type) {
case CounterMessage:
if v == 0 {
a1.Stop()
return
}
}
// Respond to actor2.
a2.inbox <- "ping"
})
// Stateful a2 actor.
n := CounterMessage(32)
a2 = NewActor(func(message any) {
log.Printf("actor2: %v", message)
n -= 1
a1.inbox <- n
})
defer a2.Stop()
go a2.Start() // Kick off a2
// Kick off first message
a2.inbox <- "hello"
// Program waits for a1 to finish.
a1.Start()
}
func NewActor(handleFunc func(any)) *Actor {
return &Actor{
handleFunc: handleFunc,
inbox: make(chan any),
done: make(chan struct{}),
}
}
type Actor struct {
handleFunc func(any)
inbox chan any
done chan struct{}
}
func (a *Actor) Start() {
for {
select {
case <-a.done:
return
case message := <-a.inbox:
a.handleFunc(message)
}
}
}
func (a *Actor) Stop() { close(a.done) }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment