Skip to content

Instantly share code, notes, and snippets.

@nevans
Created September 11, 2012 20:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nevans/3701649 to your computer and use it in GitHub Desktop.
Save nevans/3701649 to your computer and use it in GitHub Desktop.
celluloid supervisor that attempts to run the called method no matter what
#!/usr/bin/env ruby
# encoding: UTF-8
require "celluloid"
class BustedActor
include Celluloid
include Celluloid::Logger
def works_great; 42 end
def broken; raise "hell" end
end
# A callback/linking approach would be better than polling with retry
# but this should get the job done too.
#
# One caveat is that async messages still might not get through to dead actors,
# because there's no way to reliably generate DeadActorErrors for async calls.
class RetryingSupervisorProxy
include Celluloid::Logger
class NoActorError < RuntimeError; end
attr_reader :supervisor, :max_retries, :retry_wait
def initialize(supervisor, max_retries=20, retry_wait=0.1)
@supervisor = supervisor
@max_retries = max_retries
@retry_wait = retry_wait
@retries = 0
end
def method_missing(method, *args, &block)
actor = supervisor.actors.first or raise NoActorError
actor.send(method, *args, &block).tap do @retries = 0 end
rescue NoActorError, Celluloid::DeadActorError
if (@retries += 1) < max_retries
info "retrying"
sleep retry_wait
retry
else
raise
end
end
end
proxy = RetryingSupervisorProxy.new(BustedActor.supervise)
$stderr.puts "**** works_great: #{proxy.works_great.inspect}"
$stderr.puts "**** broken: #{(proxy.broken rescue :rescued).inspect}"
$stderr.puts "**** works_great: #{proxy.works_great.inspect}"
**** works_great: 42
E, [2012-09-11T16:38:05.474263 #18485] ERROR -- : BustedActor crashed!
RuntimeError: hell
celluloid-retrying_supervisor_proxy.rb:9:in `broken'
/home/nick/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/celluloid-0.12.0/lib/celluloid/calls.rb:57:in `dispatch'
/home/nick/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/celluloid-0.12.0/lib/celluloid/actor.rb:320:in `block in handle_message'
/home/nick/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/celluloid-0.12.0/lib/celluloid/tasks/task_fiber.rb:22:in `block in initialize'
**** broken: :rescued
I, [2012-09-11T16:38:05.475256 #18485] INFO -- : retrying
**** works_great: 42
I, [2012-09-11T16:38:05.576849 #18485] INFO -- : Terminating 4 actors...
I, [2012-09-11T16:38:05.578759 #18485] INFO -- : Shutdown completed cleanly
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment