lib/celluloid.rb in celluloid-0.15.2 vs lib/celluloid.rb in celluloid-0.16.0.pre
- old
+ new
@@ -1,50 +1,67 @@
require 'logger'
require 'thread'
require 'timeout'
require 'set'
-if defined?(JRUBY_VERSION) && JRUBY_VERSION == "1.7.3"
- raise "Celluloid is broken on JRuby 1.7.3. Please upgrade to 1.7.4+"
-end
-
module Celluloid
- VERSION = '0.15.2'
- Error = Class.new StandardError
+ # Expose all instance methods as singleton methods
+ extend self
- extend self # expose all instance methods as singleton methods
+ VERSION = '0.16.0.pre'
+ # Linking times out after 5 seconds
+ LINKING_TIMEOUT = 5
+
# Warning message added to Celluloid objects accessed outside their actors
BARE_OBJECT_WARNING_MESSAGE = "WARNING: BARE CELLULOID OBJECT "
class << self
- attr_accessor :internal_pool # Internal thread pool
+ attr_writer :actor_system # Default Actor System
attr_accessor :logger # Thread-safe logger class
attr_accessor :task_class # Default task type to use
attr_accessor :shutdown_timeout # How long actors have to terminate
+ def actor_system
+ if Thread.current.celluloid?
+ Thread.current[:celluloid_actor_system] or raise Error, "actor system not running"
+ else
+ Thread.current[:celluloid_actor_system] || @actor_system or raise Error, "Celluloid is not yet started; use Celluloid.boot"
+ end
+ end
+
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 :proxy_class, :default => Celluloid::CellProxy
klass.property :task_class, :default => Celluloid.task_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
+ klass.property :exit_handler_name
klass.send(:define_singleton_method, :trap_exit) do |*args|
- exit_handler(*args)
+ exit_handler_name(*args)
end
+
+ klass.send(:define_singleton_method, :exclusive) do |*args|
+ if args.any?
+ exclusive_methods(*exclusive_methods, *args)
+ else
+ exclusive_actor true
+ end
+ end
end
# Are we currently inside of an actor?
def actor?
!!Thread.current[:celluloid_actor]
@@ -67,11 +84,11 @@
alias_method :cpus, :cores
alias_method :ncpus, :cores
# Perform a stack dump of all actors to the given output object
def stack_dump(output = STDERR)
- Celluloid::StackDump.new.dump(output)
+ actor_system.stack_dump.print(output)
end
alias_method :dump, :stack_dump
# Detect if a particular call is recursing through multiple actors
def detect_recursion
@@ -104,22 +121,19 @@
init
start
end
def init
- self.internal_pool = InternalPool.new
+ @actor_system = ActorSystem.new
end
- # Launch default services
- # FIXME: We should set up the supervision hierarchy here
def start
- Celluloid::Notifications::Fanout.supervise_as :notifications_fanout
- Celluloid::IncidentReporter.supervise_as :default_incident_reporter, STDERR
+ actor_system.start
end
def running?
- internal_pool
+ actor_system && actor_system.running?
end
def register_shutdown
return if @shutdown_registered
# Terminate all actors at exit
@@ -137,45 +151,11 @@
@shutdown_registered = true
end
# Shut down all running actors
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
+ actor_system.shutdown
end
def version
VERSION
end
@@ -183,21 +163,21 @@
# Class methods added to classes which include Celluloid
module ClassMethods
# Create a new actor
def new(*args, &block)
- proxy = Actor.new(allocate, actor_options).proxy
+ proxy = Cell.new(allocate, behavior_options, actor_options).proxy
proxy._send_(:initialize, *args, &block)
proxy
end
alias_method :spawn, :new
# Create a new actor and link to the current one
def new_link(*args, &block)
raise NotActorError, "can't link outside actor context" unless Celluloid.actor?
- proxy = Actor.new(allocate, actor_options).proxy
+ proxy = Cell.new(allocate, behavior_options, actor_options).proxy
Actor.link(proxy)
proxy._send_(:initialize, *args, &block)
proxy
end
alias_method :spawn_link, :new_link
@@ -231,33 +211,35 @@
# Run an actor in the foreground
def run(*args, &block)
Actor.join(new(*args, &block))
end
- # Mark methods as running exclusively
- def exclusive(*methods)
- if methods.empty?
- @exclusive_methods = :all
- elsif !defined?(@exclusive_methods) || @exclusive_methods != :all
- @exclusive_methods ||= Set.new
- @exclusive_methods.merge methods.map(&:to_sym)
- end
+ def actor_system
+ Celluloid.actor_system
end
# Configuration options for Actor#new
def actor_options
{
+ :actor_system => actor_system,
:mailbox_class => mailbox_class,
:mailbox_size => mailbox_size,
- :proxy_class => proxy_class,
:task_class => task_class,
- :exit_handler => exit_handler,
- :exclusive_methods => defined?(@exclusive_methods) ? @exclusive_methods : nil,
- :receiver_block_executions => execute_block_on_receiver
+ :exclusive => exclusive_actor,
}
end
+ def behavior_options
+ {
+ :proxy_class => proxy_class,
+ :exclusive_methods => exclusive_methods,
+ :exit_handler_name => exit_handler_name,
+ :finalizer => finalizer,
+ :receiver_block_executions => execute_block_on_receiver,
+ }
+ end
+
def ===(other)
other.kind_of? self
end
end
@@ -289,23 +271,24 @@
yield current_actor
current_actor
end
# Obtain the name of the current actor
- def name
- Actor.name
+ def registered_name
+ Actor.registered_name
end
+ alias_method :name, :registered_name
def inspect
return "..." if Celluloid.detect_recursion
str = "#<"
if leaked?
str << Celluloid::BARE_OBJECT_WARNING_MESSAGE
else
- str << "Celluloid::ActorProxy"
+ str << "Celluloid::CellProxy"
end
str << "(#{self.class}:0x#{object_id.to_s(16)})"
str << " " unless instance_variables.empty?
@@ -333,11 +316,11 @@
raise AbortError.new(cause)
end
# Terminate this actor
def terminate
- Thread.current[:celluloid_actor].proxy.terminate!
+ Thread.current[:celluloid_actor].behavior_proxy.terminate!
end
# Send a signal with the given name to all waiting methods
def signal(name, value = nil)
Thread.current[:celluloid_actor].signal name, value
@@ -456,19 +439,25 @@
Future.new(&block).value
end
# Handle async calls within an actor itself
def async(meth = nil, *args, &block)
- Thread.current[:celluloid_actor].proxy.async meth, *args, &block
+ Thread.current[:celluloid_actor].behavior_proxy.async meth, *args, &block
end
# Handle calls to future within an actor itself
def future(meth = nil, *args, &block)
- Thread.current[:celluloid_actor].proxy.future meth, *args, &block
+ Thread.current[:celluloid_actor].behavior_proxy.future meth, *args, &block
end
end
+if defined?(JRUBY_VERSION) && JRUBY_VERSION == "1.7.3"
+ raise "Celluloid is broken on JRuby 1.7.3. Please upgrade to 1.7.4+"
+end
+
+require 'celluloid/exceptions'
+
require 'celluloid/calls'
require 'celluloid/call_chain'
require 'celluloid/condition'
require 'celluloid/thread'
require 'celluloid/core_ext'
@@ -480,10 +469,11 @@
require 'celluloid/logger'
require 'celluloid/mailbox'
require 'celluloid/evented_mailbox'
require 'celluloid/method'
require 'celluloid/properties'
+require 'celluloid/handlers'
require 'celluloid/receivers'
require 'celluloid/registry'
require 'celluloid/responses'
require 'celluloid/signals'
require 'celluloid/stack_dump'
@@ -493,23 +483,28 @@
require 'celluloid/thread_handle'
require 'celluloid/uuid'
require 'celluloid/proxies/abstract_proxy'
require 'celluloid/proxies/sync_proxy'
+require 'celluloid/proxies/cell_proxy'
require 'celluloid/proxies/actor_proxy'
require 'celluloid/proxies/async_proxy'
require 'celluloid/proxies/future_proxy'
require 'celluloid/proxies/block_proxy'
require 'celluloid/actor'
+require 'celluloid/cell'
require 'celluloid/future'
+require 'celluloid/actor_system'
require 'celluloid/pool_manager'
require 'celluloid/supervision_group'
require 'celluloid/supervisor'
require 'celluloid/notifications'
require 'celluloid/logging'
require 'celluloid/legacy' unless defined?(CELLULOID_FUTURE)
+
+$CELLULOID_MONITORING = false
# Configure default systemwide settings
Celluloid.task_class = Celluloid::TaskFiber
Celluloid.logger = Logger.new(STDERR)
Celluloid.shutdown_timeout = 10