25
An Actor Model in Go Bryan Boreham, Weaveworks @bboreham

An Actor Model in Go

Embed Size (px)

Citation preview

Page 1: An Actor Model in Go

An Actor Model in GoBryan Boreham, Weaveworks@bboreham

Page 2: An Actor Model in Go
Page 3: An Actor Model in Go

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.

Page 4: An Actor Model in Go

Actors’ Advocacy

• Good for highly concurrent systems

• Easier to write

• Easier to reason about

Page 5: An Actor Model in Go

This has been a learning experience

Page 6: An Actor Model in Go

Some predictions

• I’ll get to those later

Page 7: An Actor Model in Go

My life as a Gopher

Page 8: An Actor Model in Go

ConnectionMaker

Weave Net ConnectionMaker

Page 9: An Actor Model in Go

ConnectionMaker

Weave Net ConnectionMaker

Page 10: An Actor Model in Go

ConnectionMaker

Weave Net ConnectionMaker

Page 11: An Actor Model in Go

ConnectionMaker Properties

• Async between callers and actions

• Sync during connection attempts

• Timer-driven events

Page 12: An Actor Model in Go

Actor

Page 13: An Actor Model in Go

Actors

Page 14: An Actor Model in Go

Actor Outline in Go

• Actor → struct + goroutine

• Mailbox → chan

func StartActor() *Actor {ch := make(chan action, size)actor := &Actor{ ... }go actor.actorLoop(ch)return actor

}

func (actor *Actor) DoSomething() {actor.actionChan <- something

}

func (actor *Actor) actorLoop( ch <-chan action) {

for {action := <-ch// deal with action

}}

🤔

🤔

Page 15: An Actor Model in Go

ConnectionMaker in Go

type action func()

func (cm *ConnectionMaker) Add(address string) {cm.actionChan <- func() {

cm.addConnection(address)}

}

Page 16: An Actor Model in Go

ConnectionMaker Loop

func (cm *ConnectionMaker) actorLoop(ch <-chan action) {timer := time.NewTimer(duration)for {

select {case action := <-ch:

action()case <-timer.C:

retryConnections()}

}}

Page 17: An Actor Model in Go

Actions with return values

func (cm *ConnectionMaker) String() string {resultChan := make(chan string, 0)cm.actionChan <- func() {

resultChan <- cm.status()}return <-resultChan

}

Page 18: An Actor Model in Go

What size should the chan be?

• 0

• 1

• N

• ∞

Page 19: An Actor Model in Go

Non-blocking send

func (actor *SomeActor) TryTo(something) {select {case actor.actionChan <- func() {

// do the thing }:default:

// chan is full; throw it away }

}

Page 20: An Actor Model in Go

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

Page 21: An Actor Model in Go

In Practice

Pro:

• No lock/unlock

• Simple model

• Identifies goroutines

Con:

• Debugging/testing

• Single reader/writer

• No framework!

Page 22: An Actor Model in Go

Deadlock, Feb 15 2015

localPeer.queryLoop

connection.queryLoop

handleAddConnection

connection.sendGossip

Messagehandle

SetEstablished

localPeer.ConnEstablished

chan

chan

Page 23: An Actor Model in Go

Predictions

• You’ll say “just use a mutex”

• You’ll say “that’s what I’m doing anyway”

Page 24: An Actor Model in Go

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

Page 25: An Actor Model in Go

Thank You

Gopher images by Renee French http://reneefrench.blogspot.com/