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

actor_system[W]
group_class[RW]
log_actor_crashes[RW]
logger[RW]
shutdown_timeout[RW]
task_class[RW]

Public Class Methods

actor?() click to toggle source

Are we currently inside of an actor?

# File lib/celluloid.rb, line 81
def actor?
  !!Thread.current[:celluloid_actor]
end
actor_system() click to toggle source
# 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
boot() click to toggle source
# File lib/celluloid.rb, line 145
def boot
  init
  start
end
cores() click to toggle source

Obtain the number of CPUs in the system

# File lib/celluloid.rb, line 96
def cores
  Internals::CPUCounter.cores
end
Also aliased as: cpus, ncpus
cpus()
Alias for: cores
detect_recursion() click to toggle source

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
dump(output = STDERR)
Alias for: stack_dump
exception_handler(&block) click to toggle source

Define an exception handler for actor crashes

# File lib/celluloid.rb, line 131
def exception_handler(&block)
  Internals::Logger.exception_handler(&block)
end
included(klass) click to toggle source
# 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
init() click to toggle source
# File lib/celluloid.rb, line 150
def init
  @actor_system = Actor::System.new
end
mailbox() click to toggle source

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
ncpus()
Alias for: cores
public_registry() click to toggle source
# File lib/celluloid.rb, line 114
def public_registry
  actor_system.public_registry
end
register_shutdown() click to toggle source
# 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
running?() click to toggle source
# File lib/celluloid.rb, line 158
def running?
  actor_system && actor_system.running?
end
shutdown() click to toggle source

Shut down all running actors

# File lib/celluloid.rb, line 183
def shutdown
  actor_system.shutdown
end
stack_dump(output = STDERR) click to toggle source

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
Also aliased as: dump
stack_summary(output = STDERR) click to toggle source

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
Also aliased as: summarize
start() click to toggle source
# File lib/celluloid.rb, line 154
def start
  actor_system.start
end
summarize(output = STDERR)
Alias for: stack_summary
suspend(status, waiter) click to toggle source
# 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
uuid() click to toggle source

Generate a Universally Unique Identifier

# File lib/celluloid.rb, line 91
def uuid
  Internals::UUID.generate
end
version() click to toggle source
# File lib/celluloid.rb, line 187
def version
  VERSION
end

Public Instance Methods

abort(cause) click to toggle source

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
after(interval, &block) click to toggle source

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
async(meth = nil, *args, &block) click to toggle source

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
call_chain_id() click to toggle source

Obtain the UUID of the current call chain

# File lib/celluloid.rb, line 347
def call_chain_id
  Internals::CallChain.current_id
end
current_actor() click to toggle source

Obtain the #current_actor

# File lib/celluloid.rb, line 342
def current_actor
  Actor.current
end
defer(&block) click to toggle source

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
every(interval, &block) click to toggle source

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
exclusive(&block) click to toggle source

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
exclusive?() click to toggle source

Are we currently exclusive

# File lib/celluloid.rb, line 425
def exclusive?
  task = Thread.current[:celluloid_task]
  task && task.exclusive?
end
future(meth = nil, *args, &block) click to toggle source

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
linked_to?(actor) click to toggle source

Is this actor linked to another?

# File lib/celluloid.rb, line 387
def linked_to?(actor)
  Actor.linked_to?(actor)
end
monitor(actor) click to toggle source

Watch for exit events from another actor

# File lib/celluloid.rb, line 362
def monitor(actor)
  Actor.monitor(actor)
end
monitoring?(actor) click to toggle source

Are we monitoring another actor?

# File lib/celluloid.rb, line 382
def monitoring?(actor)
  Actor.monitoring?(actor)
end
receive(timeout = nil, &block) click to toggle source

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
signal(name, value = nil) click to toggle source

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(interval) click to toggle source

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
tasks() click to toggle source

Obtain the running tasks for this actor

# File lib/celluloid.rb, line 352
def tasks
  Thread.current[:celluloid_actor].tasks.to_a
end
terminate() click to toggle source

Terminate this actor

# File lib/celluloid.rb, line 327
def terminate
  Thread.current[:celluloid_actor].behavior_proxy.terminate!
end
timeout(duration) { || ... } click to toggle source

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
unmonitor(actor) click to toggle source

Stop waiting for exit events from another actor

# File lib/celluloid.rb, line 367
def unmonitor(actor)
  Actor.unmonitor(actor)
end
wait(name) click to toggle source

Wait for the given signal

# File lib/celluloid.rb, line 337
def wait(name)
  Thread.current[:celluloid_actor].wait name
end