But merely starting a Thread
you not leave you in a deadlock
hell
Friday, March 22, 13
Slide 19
Slide 19 text
things start to break when you
have...
Friday, March 22, 13
Slide 20
Slide 20 text
Mutable Shared
State
Friday, March 22, 13
Slide 21
Slide 21 text
Mutable shared state is the
root of all evil
(together with money, premature optimizations, and semicolons)
Friday, March 22, 13
Slide 22
Slide 22 text
We can deal with concurrency
issues by controlling mutability
Friday, March 22, 13
Slide 23
Slide 23 text
There are many techniques for
that
Friday, March 22, 13
Slide 24
Slide 24 text
STM
Atomic Operations
Pure Functions
Channels
Friday, March 22, 13
Slide 25
Slide 25 text
and also...
Friday, March 22, 13
Slide 26
Slide 26 text
Actors
Friday, March 22, 13
Slide 27
Slide 27 text
Think of concurrent Objects
Friday, March 22, 13
Slide 28
Slide 28 text
All communication is done with
async immutable messages
Friday, March 22, 13
Slide 29
Slide 29 text
No shared state!
Friday, March 22, 13
Slide 30
Slide 30 text
Actor
Actor
Actor
Text
message
State
message
message
Friday, March 22, 13
Slide 31
Slide 31 text
messages
async
Actor
mailbox
mutable state
Friday, March 22, 13
Slide 32
Slide 32 text
Each actor acts as a single
threaded program, but they exist
concurrently
Friday, March 22, 13
Slide 33
Slide 33 text
Actors and OO, a long story...
Friday, March 22, 13
Slide 34
Slide 34 text
1973 - Actors
1972 - SmallTalk
Friday, March 22, 13
Slide 35
Slide 35 text
“OOP means only messaging, local
retention and protection and hiding of state
processing”
Alan Kay
Friday, March 22, 13
Slide 36
Slide 36 text
“Actors means only messaging, local
retention and protection and hiding of state
processing”
Me
Friday, March 22, 13
Slide 37
Slide 37 text
Actors
OO before anyone heard of that!
Friday, March 22, 13
Slide 38
Slide 38 text
Popular in functional languages,
like Erlang and Scala
Friday, March 22, 13
Slide 39
Slide 39 text
what about Ruby?
Friday, March 22, 13
Slide 40
Slide 40 text
Ruby has a somewhat shaky
relationship with concurrency
Friday, March 22, 13
Slide 41
Slide 41 text
“Ruby does not scale!
Parallelism is impossible!
NodeJS is so much faster”
The Internet
Friday, March 22, 13
Slide 42
Slide 42 text
Well, not really!
It’s complicated
Friday, March 22, 13
Slide 43
Slide 43 text
Recent emphasis on
concurrency, specially by
alternative implementations
Friday, March 22, 13
Slide 44
Slide 44 text
many different Actors
implementations for Ruby
Friday, March 22, 13
Slide 45
Slide 45 text
Celluloid
Actors.rb
Girl-Friday
Friday, March 22, 13
Slide 46
Slide 46 text
Celluloid
Friday, March 22, 13
Slide 47
Slide 47 text
Concurrency
+
Object Orientation
Friday, March 22, 13
Slide 48
Slide 48 text
class MyActor
include Celluloid
def hard_work
sleep 100
“job done!”
end
end
Friday, March 22, 13
Slide 49
Slide 49 text
“Wait a sec! It’s just a normal
looking class!”
Friday, March 22, 13
Slide 50
Slide 50 text
Give me my Mailbox!
Friday, March 22, 13
Slide 51
Slide 51 text
The secret is the use of Proxies
and Futures
Friday, March 22, 13
Slide 52
Slide 52 text
Normal Call
actor = MyActor.new
=> #
# new gets you a proxy object
actor.hard_work
(100s later...)
=> “job done!”
# that answers normally to method
# calls
Friday, March 22, 13
Slide 53
Slide 53 text
Normal Call
another Proxy
mailbox
Actor
mailbox
Friday, March 22, 13
Slide 54
Slide 54 text
actor.async.hard_work
(instantaneous)
=> nil
# Proxy fires the message immediately
# and returns nil
Async Call
Friday, March 22, 13
Slide 55
Slide 55 text
Async Call
another Proxy
mailbox
Actor
mailbox
Nil
Friday, March 22, 13
Slide 56
Slide 56 text
future = actor.future.hard_work
(instantaneous)
=> #
# Proxy returns a future object
future.value
(blocking call)
=> “job done!”
# only blocks when value is called
Calls with Future
Friday, March 22, 13
Slide 57
Slide 57 text
Calls with Future
another Actor
mailbox
Proxy
Future
Friday, March 22, 13
Slide 58
Slide 58 text
Everything is underlined by
Ruby Fibers and Threads
Friday, March 22, 13
Slide 59
Slide 59 text
What if an actor fails?
Friday, March 22, 13
Slide 60
Slide 60 text
Fault tolerance model inspired
by Erlang
Friday, March 22, 13
Slide 61
Slide 61 text
Turn it off and on again!
Friday, March 22, 13
Slide 62
Slide 62 text
Linking
Supervisor
Supervisor Groups
Friday, March 22, 13
Slide 63
Slide 63 text
class Worker
include Celluloid
def initialize(website)
@website = website
end
def work
Net::HTTP.get(@website)
end
end
Working with Supervisors
Friday, March 22, 13
Slide 64
Slide 64 text
Worker.supervise_as :wk, ‘www.google.com’
=>#
# returns a supervisor and also boots the
# actor
worker = Celluloid::Actors[:wk]
worker.work
# supervisor takes care of restarting
# actor in case of exceptions
Working with Supervisors
Friday, March 22, 13
Slide 65
Slide 65 text
Very cool this Actor thing, but
does it makes any difference?
Friday, March 22, 13
Slide 66
Slide 66 text
The Sidekiq Case
“we replaced 12-15 EC2 medium instances running 4
delayed_job processes each with a single EC2 medium instance
running 4 sidekiq workers with 25 concurrency each. The final
tally is something like $2500 less per month in EC2 costs.”
Friday, March 22, 13
Slide 67
Slide 67 text
concluding
Friday, March 22, 13
Slide 68
Slide 68 text
Concurrency is hard
Friday, March 22, 13
Slide 69
Slide 69 text
but ignoring it won’t make it go
away
Friday, March 22, 13
Slide 70
Slide 70 text
There are many available
models and solutions
Friday, March 22, 13
Slide 71
Slide 71 text
Ruby is lagging behind on that
front
Friday, March 22, 13