public
Created — forked from mperham/ex2.rb

More complex supervisor with worker pool example

  • Download Gist
ex2.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
require 'actor'
require 'rubinius_fix'
 
Ready = Struct.new(:this)
Work = Struct.new(:msg)
 
processor = Proc.new do |msg|
raise msg.to_s if msg % 7 == 0
print "Doing some hard work for #{msg}, boss!\n"
end
 
@supervisor = Actor.spawn do
supervisor = Actor.current
work_loop = Proc.new do
loop do
work = Actor.receive
result = processor.call(work.msg)
supervisor << Ready[Actor.current]
end
end
 
Actor.trap_exit = true
ready_workers = []
10.times do |x|
# start N workers
ready_workers << Actor.spawn_link(&work_loop)
end
 
loop do
Actor.receive do |f|
f.when(Ready) do |who|
# TODO
end
f.when(Work) do |work|
ready_workers.pop << work
end
f.when(Actor::DeadActorError) do |exit|
print "Actor exited with message: #{exit.reason}\n"
ready_workers << Actor.spawn_link(&work_loop)
end
end
end
end
 
10.times do |idx|
@supervisor << Work[idx]
end
sleep 1
rubinius_fix.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
if RUBY_ENGINE == 'rbx' && Rubinius::VERSION < '1.2.4'
puts "Loading rubinius actor monkeypatches"
class Actor
 
# Monkeypatch so this works with Rubinius 1.2.3 (latest).
# 1.2.4 should have the necessary fix included.
def notify_exited(actor, reason)
exit_message = nil
@lock.receive
begin
return self unless @alive
@links.delete(actor)
if @trap_exit
exit_message = DeadActorError.new(actor, reason)
elsif reason
@interrupts << DeadActorError.new(actor, reason)
if @filter
@filter = nil
@ready << nil
end
end
ensure
@lock << nil
end
send exit_message if exit_message
self
end
end
end

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.