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

Ruby goes to Hollywood

elise_huard
September 26, 2011

Ruby goes to Hollywood

Actors are a way to handle concurrent (and parallel) program in a relatively simple way. I give examples in Ruby, but also from other languages like Erlang and Scala.

elise_huard

September 26, 2011
Tweet

More Decks by elise_huard

Other Decks in Programming

Transcript

  1. Text class Barber include Celluloid::Actor attr_accessor :status def initialize(shop) @shop

    = shop end def cut_customer(name) puts " cutting customer #{name}" sleep(rand(5)) accident = rand(2) if accident puts " finished cutting #{name}" else puts " *** whoops, chopped #{name}'s head off ***" end shop.customer_leaves! end (...) end
  2. Text class Shop include Celluloid::Actor def initialize @barber = Barber.new(self)

    @chairs = [] puts "lights on ..." end def waiting_line @chairs.size end def new_customer(name) puts " customer arriving: #{name}" if waiting_line > 3 puts "*** sorry, #{name}, no room ***" else @chairs << name @barber.cut_customer!(name) end end def customer_leaves @chairs.shift end end
  3. Text shop = Shop.new ['jack', 'john', 'henry', 'tom', 'bob'].each do

    |customer| shop.new_customer!(customer) end shop.report
  4. %% shop %% barber_shop() -> io:format("lights on ... ~n"), ShopPid

    = self(), BarberPid = spawn(fun() -> barber(ShopPid) end), barber_shop_in_business(BarberPid, []). barber_shop_in_business(BarberPid, CustomersInChairs) -> receive {cut, Customer} -> % pop customer from list when hair is being cut remove_customer(BarberPid, CustomersInChairs, Customer); barbercheck -> respond_to_barber(BarberPid, CustomersInChairs); Customer -> io:format("~p arrives~n",[Customer]), % should check the number of customers waiting first % if all full: customer turned away add_customer_if_available(BarberPid, CustomersInChairs, Customer) end.
  5. Text %% barber %% barber(ShopPid) -> ShopPid ! barbercheck, receive

    wakeup -> barber(ShopPid); {customer, Customer} -> cut(ShopPid, Customer), barber(ShopPid) end. cut(ShopPid, Name) -> io:format("cutting ~p~n", [Name]), % take customer -> can be removed from waiting chairs ShopPid ! {cut, Name}, timer:sleep(random:uniform(10000)), io:format("finished cutting: ~p~n", [Name]).
  6. Text scenario() -> ShopPid = start_shop(), % send customers to

    the shop ShopPid ! 'john', ShopPid ! 'joe', timer:sleep(20000), ShopPid ! 'kevin', ShopPid ! 'richard', main_end.
  7. Text object Shop def initialize shop_pid = Process.current barber_pid =

    Process.spawn -> Barber.loop(shop_pid) @('barber_pid: barber_pid, 'shop_pid: shop_pid) end def loop(customers_in_chairs) IO.puts "shop loop #{customers_in_chairs}" receive match {'cut, customer} if customers_in_chairs.include?(customer) loop(customers_in_chairs.delete(customer)) else loop(customers_in_chairs) end match 'barbercheck IO.puts "barber checking ..." respond_to_barber(customers_in_chairs) match {'customer, customer} IO.puts("new customer #{customer}") add_customer(customers_in_chairs, customer) end end (...)
  8. Text module Barber def loop(shop_pid) shop_pid <- 'barbercheck receive match

    'wakeup IO.puts "wakeup" loop(shop_pid) match {'customer, customer} cut_hair(shop_pid, customer) loop(shop_pid) end end def cut_hair(shop_pid, customer) IO.puts "cutting customer #{customer}" shop_pid <- {'cut, customer} IO.puts "finished cutting customer #{customer}" end end
  9. Text pid = Process.spawn -> Shop.new.loop([]) IO.puts pid pid <-

    {'customer, "jack"} pid <- {'customer, "bob"}
  10. Text class Conductor < Akka::UntypedActor def self.spawn actor = Akka::Actors.actor_of

    { new } actor.set_dispatcher(Akka::Dispatchers.newThreadBasedDispatcher(actor)) actor.start end def onReceive(msg) case msg when "go" puts 'play score' play_guitar play_drum when "done drumming" play_end_drum when "done guitar" play_guitar else puts "msg: #{msg}" end end def play_end_drum puts "play end drum" end_drum = EndDrum.spawn end_drum.send_one_way("play", context) end (...) end
  11. Text class Musician < Akka::UntypedActor include Music def self.spawn actor

    = Akka::Actors.actor_of { new } actor.set_dispatcher(Akka::Dispatchers.newThreadBasedDispatche r(actor)) actor.start end def onReceive(msg) case msg when "play" @conductor = context.sender.get @conductor = Akka::Actors.registry.actor_for(@conductor.uuid).get play(@conductor) else puts "msg: #{msg}" end end end
  12. Kiitos Kuunteluun! Speaker @elise_huard Conference Frozen Rails 2011 Sponsor Forward

    Pictures By The Waterfront Vertigo Casablanca Tarzan Wizard of Oz Some like it hot King Kong Citizen Kane Documentation http://www.delicious.com/elisehuard/concurrency