An overview of the actor-based Ruby framework, Celluloid. Includes a basic introduction to why one might want to use Ruby to do threaded programming and what the actor model might provide. Includes a few code examples.
Thread.new is not much fun Evented callbacks R fun and reactors are cool Rewriting libs for eventmachine is not so fun Synchrony is kind of awkward and magicky Languages are fun, especially Ruby (but this isn’t Boulder Erlang Group) Monday, March 18, 13
stuff, and eveaded and thrented whatnots You can make a reactor thread, and then block it, just for fun Pretty easy to tell how to arrange things Monday, March 18, 13
actor is its own entity that can send and receive messages. Each actor is addressable by any other actor that knows its identifier Actors can create new actors Monday, March 18, 13
in your body, don’t mutate objects that have gone through the cell wall as messages. This is how celluloid guarantees thread safety. Monday, March 18, 13
gets its own thread Method calls to an actor are actually proxied and wrapped in a fiber/thread But it isn’t awkward like synchrony Finally, some code: Monday, March 18, 13
Fiona Jill Karen Lee Moira Samantha Sangeeta Serena Tessa Tom) def initialize(voice=nil) @voice = voice.blank? ? VOICES.shuffle[0] : voice end def say(text) Benchmark.realtime do `say --voice #{@voice} #{text}` end end end Monday, March 18, 13
Fiona Jill Karen Lee Moira Samantha Sangeeta Serena Tessa Tom) def initialize(voice=nil) @voice = voice.blank? ? VOICES.shuffle[0] : voice end def say(text) Benchmark.realtime do `say --voice #{@voice} #{text}` end end end > SayActor.new.async.say("Hello World"); SayActor.new.async.say("Howdy y'all") => nil Fire and forget But no return value... Monday, March 18, 13
Fiona Jill Karen Lee Moira Samantha Sangeeta Serena Tessa Tom) def initialize(voice=nil) @voice = voice.blank? ? VOICES.shuffle[0] : voice end def say(text) Benchmark.realtime do `say --voice #{@voice} #{text}` end end end > SayActor.new.future.say("Hello World").value => 1.768051 Futures capture values and block on #value Back to blocking... Monday, March 18, 13
Fiona Jill Karen Lee Moira Samantha Sangeeta Serena Tessa Tom) def initialize(voice=nil) @voice = voice.blank? ? VOICES.shuffle[0] : voice end def say(text) Benchmark.realtime do `say --voice #{@voice} #{text}` end end end > f = [] > f << SayActor.new.future.say("Howdy y'all") > f << SayActor.new.future.say("Hello World") > f.sum(&:value) => 3.27545 Still Boring... Fully asynchronous with return values Monday, March 18, 13
other actors. Use Celluloid::Actor.current (or if you are in your actor, just Actor.current) to pass the celluloid proxy object instead Monday, March 18, 13
the state of objects you pass to other actors (sometimes it is good to marshall data) You shouldn’t need fibers and threads and mutexes any more... Monday, March 18, 13