module Celluloid
TODO: Remove link to Interal::Logger
Constants
- ActorSystem
- BARE_OBJECT_WARNING_MESSAGE
Warning message added to Celluloid objects accessed outside their actors
- EventedMailbox
- InternalPool
- LINKING_TIMEOUT
Linking times out after 5 seconds
- OWNER_IVAR
- SyncCall
- TaskFiber
- TaskThread
- VERSION
Attributes
Public Class Methods
Are we currently inside of an actor?
# File lib/celluloid.rb, line 81 def actor? !!Thread.current[:celluloid_actor] end
# File lib/celluloid.rb, line 34 def actor_system if Thread.current.celluloid? Thread.current[:celluloid_actor_system] || fail(Error, "actor system not running") else Thread.current[:celluloid_actor_system] || @actor_system || fail(Error, "Celluloid is not yet started; use Celluloid.boot") end end
# File lib/celluloid.rb, line 145 def boot init start end
Obtain the number of CPUs in the system
# File lib/celluloid.rb, line 96 def cores Internals::CPUCounter.cores end
Detect if a particular call is recursing through multiple actors
# File lib/celluloid.rb, line 119 def detect_recursion actor = Thread.current[:celluloid_actor] return unless actor task = Thread.current[:celluloid_task] return unless task chain_id = Internals::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 131 def exception_handler(&block) Internals::Logger.exception_handler(&block) end
# File lib/celluloid.rb, line 42 def included(klass) klass.send :extend, ClassMethods klass.send :include, InstanceMethods klass.send :extend, Internals::Properties klass.property :mailbox_class, default: Celluloid::Mailbox klass.property :proxy_class, default: Celluloid::Proxy::Cell klass.property :task_class, default: Celluloid.task_class klass.property :group_class, default: Celluloid.group_class klass.property :mailbox_size klass.property :exclusive_actor, default: false klass.property :exclusive_methods, multi: true klass.property :execute_block_on_receiver, default: [:after, :every, :receive], multi: true klass.property :finalizer klass.property :exit_handler_name singleton = class << klass; self; end singleton.send(:remove_method, :trap_exit) rescue nil singleton.send(:remove_method, :exclusive) rescue nil singleton.send(:define_method, :trap_exit) do |*args| exit_handler_name(*args) end singleton.send(:define_method, :exclusive) do |*args| if args.any? exclusive_methods(*exclusive_methods, *args) else exclusive_actor true end end end
# File lib/celluloid.rb, line 150 def init @actor_system = Actor::System.new end
Retrieve the mailbox for the current thread or lazily initialize it
# File lib/celluloid.rb, line 86 def mailbox Thread.current[:celluloid_mailbox] ||= Celluloid::Mailbox.new end
# File lib/celluloid.rb, line 114 def public_registry actor_system.public_registry end
# File lib/celluloid.rb, line 162 def register_shutdown return if defined?(@shutdown_registered) && @shutdown_registered # Terminate all actors at exit at_exit do sleep 0.126 # hax grace period for unnaturally terminating actors # allows "reason" in exit_handler to resolve before being destroyed 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 = $ERROR_INFO.status if $ERROR_INFO.is_a?(SystemExit) Celluloid.shutdown exit exit_status if exit_status else Celluloid.shutdown end end @shutdown_registered = true end
# File lib/celluloid.rb, line 158 def running? actor_system && actor_system.running? end
Shut down all running actors
# File lib/celluloid.rb, line 183 def shutdown actor_system.shutdown end
Perform a stack dump of all actors to the given output object
# File lib/celluloid.rb, line 103 def stack_dump(output = STDERR) actor_system.stack_dump.print(output) end
Perform a stack summary of all actors to the given output object
# File lib/celluloid.rb, line 109 def stack_summary(output = STDERR) actor_system.stack_summary.print(output) end
# File lib/celluloid.rb, line 154 def start actor_system.start end
# File lib/celluloid.rb, line 135 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
Generate a Universally Unique Identifier
# File lib/celluloid.rb, line 91 def uuid Internals::UUID.generate end
# File lib/celluloid.rb, line 187 def version VERSION end
Public Instance Methods
Raise an exception in sender context, but stay running
# File lib/celluloid.rb, line 317 def abort(cause) cause = case cause when String then RuntimeError.new(cause) when Exception then cause else fail TypeError, "Exception object/String expected, but #{cause.class} received" end fail AbortError.new(cause) end
Call a block after a given interval, returning a Celluloid::Timer object
# File lib/celluloid.rb, line 431 def after(interval, &block) Thread.current[:celluloid_actor].after(interval, &block) end
Handle async calls within an actor itself
# File lib/celluloid.rb, line 450 def async(meth = nil, *args, &block) Thread.current[:celluloid_actor].behavior_proxy.async meth, *args, &block end
Obtain the UUID of the current call chain
# File lib/celluloid.rb, line 347 def call_chain_id Internals::CallChain.current_id end
Obtain the #current_actor
# File lib/celluloid.rb, line 342 def current_actor Actor.current end
Perform a blocking or computationally intensive action inside an asynchronous group of threads, allowing the sender to continue processing other messages in its mailbox in the meantime
# File lib/celluloid.rb, line 443 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 436 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 420 def exclusive(&block) Thread.current[:celluloid_task].exclusive(&block) end
Are we currently exclusive
# File lib/celluloid.rb, line 425 def exclusive? task = Thread.current[:celluloid_task] task && task.exclusive? end
Handle calls to future within an actor itself
# File lib/celluloid.rb, line 455 def future(meth = nil, *args, &block) Thread.current[:celluloid_actor].behavior_proxy.future meth, *args, &block end
Link this actor to another, allowing it to crash or react to errors
# File lib/celluloid.rb, line 372 def link(actor) Actor.link(actor) end
Is this actor linked to another?
# File lib/celluloid.rb, line 387 def linked_to?(actor) Actor.linked_to?(actor) end
Obtain the Celluloid::Links for this actor
# File lib/celluloid.rb, line 357 def links Thread.current[:celluloid_actor].links end
Watch for exit events from another actor
# File lib/celluloid.rb, line 362 def monitor(actor) Actor.monitor(actor) end
Are we monitoring another actor?
# File lib/celluloid.rb, line 382 def monitoring?(actor) Actor.monitoring?(actor) end
Receive an asynchronous message via the actor protocol
# File lib/celluloid.rb, line 392 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 332 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 402 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 352 def tasks Thread.current[:celluloid_actor].tasks.to_a end
Terminate this actor
# File lib/celluloid.rb, line 327 def terminate Thread.current[:celluloid_actor].behavior_proxy.terminate! end
Timeout on task suspension (eg Sync calls to other actors)
# File lib/celluloid.rb, line 412 def timeout(duration) Thread.current[:celluloid_actor].timeout(duration) do yield end end
Remove links to another actor
# File lib/celluloid.rb, line 377 def unlink(actor) Actor.unlink(actor) end
Stop waiting for exit events from another actor
# File lib/celluloid.rb, line 367 def unmonitor(actor) Actor.unmonitor(actor) end
Wait for the given signal
# File lib/celluloid.rb, line 337 def wait(name) Thread.current[:celluloid_actor].wait name end