Skip to content

Instantly share code, notes, and snippets.

@arschles
Last active December 27, 2015 17:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arschles/7359999 to your computer and use it in GitHub Desktop.
Save arschles/7359999 to your computer and use it in GitHub Desktop.
package goactor
import "container/list"
import "sync"
//public types
type Message struct {
Sender Pid
Payload interface{}
}
type Unit struct{}
type Pid struct {
queue *list.List
queue_lock *sync.RWMutex
ready chan Unit
}
type Receiver func(msg Message) Unit
//send a message asynchronously to the pid
func (p Pid) Send(msg interface{}) Unit {
m := Message{Sender: p, Payload: msg}
p.queue_lock.Lock()
p.queue.PushBack(m)
go func() {
p.ready <- Unit{}
}()
p.queue_lock.Unlock()
return Unit{}
}
//run a receive loop
func recvLoop(ready chan Unit, p Pid, fn Receiver) {
<-p.ready
p.queue_lock.RLock()
elt := p.queue.Front()
if elt != nil {
p.queue.Remove(elt)
fn(elt.Value.(Message))
}
p.queue_lock.RUnlock()
recvLoop(ready, p, fn)
}
//create a new actor and return the pid, so you can send it messages
func Spawn(fn Receiver) Pid {
p := Pid{queue: list.New(), queue_lock: new(sync.RWMutex), ready: make(chan Unit)}
ready := make(chan Unit)
//start the receive loop
go recvLoop(ready, p, fn)
return p
}
/*
example usage:
pid := Spawn(func(sender chan Pid) {
sender <- "received"
})
pid.Send("abc")
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment