How the Go language can be used to implement a version of the Actor Model for concurrent programming.
Talk given at the Golang UK conference, August 2016
3. According to Wikipedia…
The actor model in computer science is a
mathematical model of concurrent computation that
treats "actors" as the universal primitives of
concurrent computation.
4. Actors’ Advocacy
• Good for highly concurrent systems
• Easier to write
• Easier to reason about
19. Non-blocking send
func (actor *SomeActor) TryTo(something) {
select {
case actor.actionChan <- func() {
// do the thing
}:
default:
// chan is full; throw it away
}
}
20. Back to the theory
• An actor can designate the behaviour to be used for the
next message it receives.
• Messages are sent to actors at addresses
• Compare CSP: processes are anonymous and
channels are named
• We use a pointer to the actor as its address
• Unbounded nondeterminism
21. In Practice
Pro:
• No lock/unlock
• Simple model
• Identifies goroutines
Con:
• Debugging/testing
• Single reader/writer
• No framework!
24. Summary
• “Do not communicate by sharing memory; instead,
share memory by communicating” - Effective Go
• Go provides the components to work in an actor style
• No framework - just type in a few lines
• Departs from Actor theory in a few ways
• In use in production for two years
- http://github.com/weaveworks/mesh
Joined Weaveworks August 2014
Weave Net largely coded as Actors:
- Connection, Peer, ConnectionMaker
These kind of attributes make coding it using locks more complicated
release lock before long-running operation
re-acquire lock after event
Each actor has its own “mailbox” and state. Only the actor can modify its own state.
Code is executed in response to messages received.
Messages are sent asynchronously.
There can be many actors.Erlang, Akka, Scala
Only one goroutine accesses the data in the struct
Everything is passed in as messages in the chan
Question: what should we use as messages?
Story of how Weave Net started with enums and moved forwards
Take time to explain how this works
0 synchronises callers and actions
N allows data to be processed in-order, up to length of queue
- two messages from the same sender will always be handled in order
Can also have a more complex data structure; merge/elide values
We used mix of sync and async
Changing the behaviour is not something we found we needed
Single thread running an action - cannot have multiple readers in parallel or multiple threads accessing different parts of the same data structure
(but can create multiple actors)
Actor theory is never blocking; Go channels are finite size