lib/celluloid.rb in celluloid-0.10.0 vs lib/celluloid.rb in celluloid-0.11.0
- old
+ new
@@ -71,12 +71,15 @@
def shutdown
Timeout.timeout(SHUTDOWN_TIMEOUT) do
actors = Actor.all
Logger.info "Terminating #{actors.size} actors..." 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
- terminators = actors.each do |actor|
+ terminators = Actor.all.each do |actor|
begin
actor.future(:terminate)
rescue DeadActorError, MailboxError
end
end
@@ -128,10 +131,29 @@
# an actor if it fails, and keep the actor registered under a given name
def supervise_as(name, *args, &block)
Supervisor.supervise_as(name, self, *args, &block)
end
+ # Create a new pool of workers. Accepts the following options:
+ #
+ # * size: how many workers to create. Default is worker per CPU core
+ # * args: array of arguments to pass when creating a worker
+ #
+ def pool(options = {})
+ PoolManager.new(self, options)
+ end
+
+ # Same as pool, but links to the pool manager
+ def pool_link(options = {})
+ PoolManager.new_link(self, options)
+ end
+
+ # Run an actor in the foreground
+ def run(*args, &block)
+ new(*args, &block).join
+ end
+
# Trap errors from actors we're linked to when they exit
def trap_exit(callback)
@exit_handler = callback.to_sym
end
@@ -172,10 +194,15 @@
Thread.current[:actor].alive?
end
# Raise an exception in caller context, but stay running
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
# Terminate this actor
def terminate
@@ -205,10 +232,15 @@
# Obtain the current_actor
def current_actor
Actor.current
end
+ # Obtain the name of the current actor
+ def name
+ Actor.name
+ end
+
# Obtain the running tasks for this actor
def tasks
Thread.current[:actor].tasks.to_a
end
@@ -278,21 +310,32 @@
# Perform a blocking or computationally intensive action inside an
# asynchronous thread pool, allowing the caller to continue processing other
# messages in its mailbox in the meantime
def defer(&block)
# This implementation relies on the present implementation of
- # Celluloid::Future, which uses an Actor to run the block
+ # Celluloid::Future, which uses a thread from InternalPool to run the block
Future.new(&block).value
end
+ # Handle async calls within an actor itself
+ def async(meth, *args, &block)
+ Actor.async Thread.current[:actor].mailbox, meth, *args, &block
+ end
+
+ # Handle calls to future within an actor itself
+ def future(meth, *args, &block)
+ Actor.future Thread.current[:actor].mailbox, meth, *args, &block
+ end
+
# Process async calls via method_missing
def method_missing(meth, *args, &block)
# bang methods are async calls
if meth.to_s.match(/!$/)
unbanged_meth = meth.to_s.sub(/!$/, '')
- call = AsyncCall.new(@mailbox, unbanged_meth, args, block)
+ args.unshift unbanged_meth
+ call = AsyncCall.new(nil, :__send__, args, block)
begin
Thread.current[:actor].mailbox << call
rescue MailboxError
# Silently swallow asynchronous calls to dead actors. There's no way
# to reliably generate DeadActorErrors for async calls, so users of
@@ -313,22 +356,23 @@
require 'celluloid/core_ext'
require 'celluloid/cpu_counter'
require 'celluloid/events'
require 'celluloid/fiber'
require 'celluloid/fsm'
+require 'celluloid/internal_pool'
require 'celluloid/links'
require 'celluloid/logger'
require 'celluloid/mailbox'
-require 'celluloid/pool'
require 'celluloid/receivers'
require 'celluloid/registry'
require 'celluloid/responses'
require 'celluloid/signals'
require 'celluloid/task'
+require 'celluloid/thread_handle'
require 'celluloid/timers'
-require 'celluloid/thread_pool'
require 'celluloid/uuid'
require 'celluloid/actor'
require 'celluloid/future'
-require 'celluloid/group'
+require 'celluloid/pool_manager'
+require 'celluloid/supervision_group'
require 'celluloid/supervisor'