Warning message added to Celluloid objects accessed outside their actors
Timer accuracy enforced by the tests (50ms)
Assume we’re on MRI, where we have the GIL. But what about IronRuby? Or MacRuby. Do people care? This will break Celluloid::StackDumps
Are we currently inside of an actor?
# File lib/celluloid.rb, line 49 def actor? !!Thread.current[:celluloid_actor] end
Obtain the number of CPUs in the system
# File lib/celluloid.rb, line 64 def cores CPUCounter.cores end
Detect if a particular call is recursing through multiple actors
# File lib/celluloid.rb, line 77 def detect_recursion actor = Thread.current[:celluloid_actor] return unless actor task = Thread.current[:celluloid_task] return unless task chain_id = CallChain.current_id actor.tasks.to_a.any? { |t| t != task && t.chain_id == chain_id } end
Define an exception handler for actor crashes
# File lib/celluloid.rb, line 89 def exception_handler(&block) Logger.exception_handler(&block) end
# File lib/celluloid.rb, line 25 def included(klass) klass.send :extend, ClassMethods klass.send :include, InstanceMethods klass.send :extend, Properties klass.property :mailbox_class, :default => Celluloid::Mailbox klass.property :proxy_class, :default => Celluloid::ActorProxy klass.property :task_class, :default => Celluloid.task_class klass.property :mailbox_size klass.property :execute_block_on_receiver, :default => [:after, :every, :receive], :multi => true klass.property :finalizer klass.property :exit_handler klass.send(:define_singleton_method, :trap_exit) do |*args| exit_handler(*args) end end
# File lib/celluloid.rb, line 108 def init self.internal_pool = InternalPool.new end
Retrieve the mailbox for the current thread or lazily initialize it
# File lib/celluloid.rb, line 54 def mailbox Thread.current[:celluloid_mailbox] ||= Celluloid::Mailbox.new end
# File lib/celluloid.rb, line 123 def register_shutdown return if @shutdown_registered # Terminate all actors at exit at_exit do if defined?(RUBY_ENGINE) && RUBY_ENGINE == "ruby" && RUBY_VERSION >= "1.9" # workaround for MRI bug losing exit status in at_exit block # http://bugs.ruby-lang.org/issues/5218 exit_status = $!.status if $!.is_a?(SystemExit) Celluloid.shutdown exit exit_status if exit_status else Celluloid.shutdown end end @shutdown_registered = true end
Shut down all running actors
# File lib/celluloid.rb, line 141 def shutdown actors = Actor.all Timeout.timeout(shutdown_timeout) do internal_pool.shutdown Logger.debug "Terminating #{actors.size} #{(actors.size > 1) ? 'actors' : 'actor'}..." if actors.size > 0 # Attempt to shut down the supervision tree, if available Supervisor.root.terminate if Supervisor.root # Actors cannot self-terminate, you must do it for them actors.each do |actor| begin actor.terminate! rescue DeadActorError end end actors.each do |actor| begin Actor.join(actor) rescue DeadActorError end end end rescue Timeout::Error Logger.error("Couldn't cleanly terminate all actors in #{shutdown_timeout} seconds!") actors.each do |actor| begin Actor.kill(actor) rescue DeadActorError, MailboxDead end end ensure internal_pool.kill end
Perform a stack dump of all actors to the given output object
# File lib/celluloid.rb, line 71 def stack_dump(output = STDERR) Celluloid::StackDump.new.dump(output) end
Launch default services FIXME: We should set up the supervision hierarchy here
# File lib/celluloid.rb, line 114 def start Celluloid::Notifications::Fanout.supervise_as :notifications_fanout Celluloid::IncidentReporter.supervise_as :default_incident_reporter, STDERR end
# File lib/celluloid.rb, line 93 def suspend(status, waiter) task = Thread.current[:celluloid_task] if task && !Celluloid.exclusive? waiter.before_suspend(task) if waiter.respond_to?(:before_suspend) Task.suspend(status) else waiter.wait end end
Raise an exception in sender context, but stay running
# File lib/celluloid.rb, line 327 def abort(cause) cause = case cause when String then RuntimeError.new(cause) when Exception then cause else raise TypeError, "Exception object/String expected, but #{cause.class} received" end raise AbortError.new(cause) end
Call a block after a given interval, returning a Celluloid::Timer object
# File lib/celluloid.rb, line 441 def after(interval, &block) Thread.current[:celluloid_actor].after(interval, &block) end
Handle async calls within an actor itself
# File lib/celluloid.rb, line 460 def async(meth = nil, *args, &block) Thread.current[:celluloid_actor].proxy.async meth, *args, &block end
Obtain the UUID of the current call chain
# File lib/celluloid.rb, line 357 def call_chain_id CallChain.current_id end
Obtain the current_actor
# File lib/celluloid.rb, line 352 def current_actor Actor.current end
Perform a blocking or computationally intensive action inside an asynchronous thread pool, allowing the sender to continue processing other messages in its mailbox in the meantime
# File lib/celluloid.rb, line 453 def defer(&block) # This implementation relies on the present implementation of # Celluloid::Future, which uses a thread from InternalPool to run the block Future.new(&block).value end
Call a block every given interval, returning a Celluloid::Timer object
# File lib/celluloid.rb, line 446 def every(interval, &block) Thread.current[:celluloid_actor].every(interval, &block) end
Run given block in an exclusive mode: all synchronous calls block the whole actor, not only current message processing.
# File lib/celluloid.rb, line 430 def exclusive(&block) Thread.current[:celluloid_task].exclusive(&block) end
Are we currently exclusive
# File lib/celluloid.rb, line 435 def exclusive? task = Thread.current[:celluloid_task] task && task.exclusive? end
Handle calls to future within an actor itself
# File lib/celluloid.rb, line 465 def future(meth = nil, *args, &block) Thread.current[:celluloid_actor].proxy.future meth, *args, &block end
Link this actor to another, allowing it to crash or react to errors
# File lib/celluloid.rb, line 382 def link(actor) Actor.link(actor) end
Is this actor linked to another?
# File lib/celluloid.rb, line 397 def linked_to?(actor) Actor.linked_to?(actor) end
Obtain the Celluloid::Links for this actor
# File lib/celluloid.rb, line 367 def links Thread.current[:celluloid_actor].links end
Watch for exit events from another actor
# File lib/celluloid.rb, line 372 def monitor(actor) Actor.monitor(actor) end
Are we monitoring another actor?
# File lib/celluloid.rb, line 392 def monitoring?(actor) Actor.monitoring?(actor) end
Receive an asynchronous message via the actor protocol
# File lib/celluloid.rb, line 402 def receive(timeout = nil, &block) actor = Thread.current[:celluloid_actor] if actor actor.receive(timeout, &block) else Celluloid.mailbox.receive(timeout, &block) end end
Send a signal with the given name to all waiting methods
# File lib/celluloid.rb, line 342 def signal(name, value = nil) Thread.current[:celluloid_actor].signal name, value end
Sleep letting the actor continue processing messages
# File lib/celluloid.rb, line 412 def sleep(interval) actor = Thread.current[:celluloid_actor] if actor actor.sleep(interval) else Kernel.sleep interval end end
Obtain the running tasks for this actor
# File lib/celluloid.rb, line 362 def tasks Thread.current[:celluloid_actor].tasks.to_a end
Terminate this actor
# File lib/celluloid.rb, line 337 def terminate Thread.current[:celluloid_actor].proxy.terminate! end
Timeout on task suspension (eg Sync calls to other actors)
# File lib/celluloid.rb, line 422 def timeout(duration) Thread.current[:celluloid_actor].timeout(duration) do yield end end
Remove links to another actor
# File lib/celluloid.rb, line 387 def unlink(actor) Actor.unlink(actor) end
Generated with the Darkfish Rdoc Generator 2.