Upgrade to Pro — share decks privately, control downloads, hide ads and more …

I wanna be an actor too - Painless multithreade...

I wanna be an actor too - Painless multithreaded programming with Celluloid

Talk su Celluloid al Ruby Social Club Firenze.
http://firenze.ruby-it.org
Video: https://vimeo.com/41551535

nolith

May 05, 2012
Tweet

More Decks by nolith

Other Decks in Programming

Transcript

  1. I wanna be an actor too Painless multithreaded programming with

    Celluloid Alessio“nolith”Caiazza [email protected] 2 maggio 2012
  2. Erlang Erlang was designed to help you writing system that

    are ... • distributed • scalable • reliable • robust • fault tollerant • massively concurrent 5 di 28
  3. Reversing a list in Erlang recursive.erl 1 −module(recursive). 2 −export([reverse/1]).

    3 4 reverse(L) −> tail reverse(L,[]). 5 6 tail reverse([],Acc) −> Acc; 7 tail reverse([H|T],Acc) −> tail reverse(T, [H|Acc]). 6 di 28
  4. Actors star.rb 1 class Star 2 include Celluloid 3 4

    def initialize(name) 5 @name = name 6 end 7 8 def set status(status) 9 @status = status 10 end 11 12 def report 13 ”#{@name} is #{@status}” 14 end 15 end 8 di 28
  5. Actors 1 load ’sources/star.rb’ ⇒ true 2 3 vin =

    Star.new ’Vin Diesel’ ⇒ #<Celluloid::Actor(Star:0x3ffd25db3a3c) @ 4 vin.set status ’driving a car!’ ⇒ ” driving a car!” 5 vin.report ⇒ ” Vin Diesel is driving a car!” 9 di 28
  6. Actors - Banged predicate method 1 load ’sources/star.rb’ ⇒ true

    2 3 vin = Star.new ’Vin Diesel’ ⇒ #<Celluloid::Actor(Star:0x3ffd25db3a3c) @ 4 vin.set status ’driving a car!’ ⇒ ” driving a car!” 5 vin.report ⇒ ” Vin Diesel is driving a car!” 6 st = ’asynchronously driving a car!’ ⇒ ” asynchronously driving a car!” 7 vin.set status! st ⇒ nil 8 vin.report ⇒ ” Vin Diesel is asynchronously driving a car!” 11 di 28
  7. Futures 1 require ’celluloid’ 2 load ’sources/star.rb’ 3 4 riddick

    = Star.new ’Richard B. Riddick’ 5 riddick.set status ’killing some Necromongers’ 6 riddick.set status ’leading the Necromongers’ 7 f = riddick.future :report 8 puts f.inspect 9 #do something 10 puts f.value 1 #<Celluloid::Future:0x007faad50c35c8> 2 Richard B. Riddick is leading the Necromongers 13 di 28
  8. Futures ... 11 future = Celluloid::Future.new do 12 sleep(2) 13

    riddick.set status ’getting bored!’ 14 riddick.report 15 end ⇒ #<Celluloid::Future:0x007feabb3ddb48> 16 17 riddick.report ⇒ ” Richard B. Riddick is leading the Necromongers” 18 future.value ⇒ ” Richard B. Riddick is getting bored!” 14 di 28
  9. Supervisor - Class definition 1 class NecroMonger 2 include Celluloid

    3 class CannotWinError < StandardError; end 4 5 def initialize 6 puts ”Spawning a NecroMonger!” 7 end 8 9 def fight(who) 10 puts ”Fighting against #{who}” 11 raise CannotWinError, ” Riddick is too strong!”if who == :riddick 12 end 13 end 16 di 28
  10. Supervisor - Usage 14 supervisor = NecroMonger.supervise 15 16 2.times

    do 17 supervisor.actor.fight! :someone 18 supervisor.actor.fight! :riddick 19 sleep 3 20 end 1 Spawning a NecroMonger! 2 Fighting against someone 3 Fighting against riddick 4 Spawning a NecroMonger! 5 Fighting against someone 6 Fighting against riddick 7 Spawning a NecroMonger! 17 di 28
  11. Links - Class definition 1 class NecroMongerFighter 2 include Celluloid

    3 attr accessor :pilot 4 5 def initialize 6 self.pilot = NecroMonger.new link 7 end 8 9 def attack riddick amanjaro 10 raise NecroMonger::CannotWinError, ” Kaboom!” 11 end 12 end 19 di 28
  12. Links - Usage 1 vehicle = NecroMongerFighter.new 2 pilot =

    vehicle.pilot 3 puts pilot.inspect 4 vehicle.attack riddick amanjaro! 5 sleep 1 6 puts pilot.inspect 7 puts vehicle.inspect 1 Spawning a NecroMonger! 2 #<Celluloid::Actor(NecroMonger:0x3fc41dddf8e4)> 3 #<Celluloid::Actor(NecroMonger) dead> 4 #<Celluloid::Actor(NecroMongerFighter) dead> 20 di 28
  13. Groups - Class definition LogisticChief 1 class LogisticChief 2 include

    Celluloid 3 4 def count assets 5 Celluloid::Actor.all 6 .select { |a| a.class.name.start with? ” Necro”} 7 .inject({}) do |sum,itm| 8 idx = itm.class.name.to sym 9 current = sum[idx] || 0 10 sum[idx] = current + 1 11 sum 12 end 13 end 22 di 28
  14. Groups - Class definition LogisticChief cont... 14 def prepare reinforcements

    15 if (count assets[:NecroMongerFighter] || 0) < 3 16 lord marshal = Actor[:lord marshal] 17 3.times { lord marshal.link NecroMongerFighter.new } 18 else 19 p ” We have enough troops Lord Marshal!” 20 end 21 end 22 end 23 di 28
  15. Groups - Class definition 1 class LordMarshal 2 include Celluloid

    3 trap exit :necromonger died 4 5 def necromonger died(actor, reason) 6 p ” Damn Riddick! #{actor.inspect} has died because of a #{rea- son.class}” 7 Actor[:logistic].prepare reinforcements! 8 end 9 end 24 di 28
  16. Groups - Class definition MainGroup 1 class MainGroup < Celluloid::Group

    2 supervise LordMarshal, :as => :lord marshal 3 supervise LogisticChief, :as => :logistic 4 def initialize 5 super 6 after(3) do 7 zhylaw = Actor[:lord marshal] 8 vehicle = NecroMongerFighter.new 9 10 zhylaw.link vehicle.pilot 11 puts Actor[:logistic].count assets 12 vehicle.attack riddick amanjaro! 13 sleep 1 14 signal :finished, Actor[:logistic].count assets 15 end 16 end 25 di 28
  17. Groups - Class definition MainGroup cont... 17 def wait backgroud

    execution 18 wait :finished 19 end 20 end 21 22 main = MainGroup.run! 23 puts main.actor.wait backgroud execution 1 Spawning a NecroMonger! 2 {:NecroMongerFighter=>1, :NecroMonger=>1} 3 ”Damn Riddick! #<Celluloid::Actor(NecroMonger) dead> has died because o 4 Spawning a NecroMonger! 5 Spawning a NecroMonger! 6 Spawning a NecroMonger! 7 {:NecroMongerFighter=>3, :NecroMonger=>3} 26 di 28
  18. Interaction over composition. Messages over shared variables. Balance load among

    different actors. Let it crash and reload a safe state.
  19. Licence - Creatives Commons Creative Commons Copyright c 2012 Alessio

    Caiazza This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License. http://creativecommons.org/licenses/by-sa/3.0/ Sources This work is typesetted with L A TEX and RubySocialClub gem. Sources are available at https://bitbucket.org/nolith/celluloid-presentation 28 di 28