lib/celluloid.rb in celluloid-0.12.3 vs lib/celluloid.rb in celluloid-0.12.4.pre
- old
+ new
@@ -22,11 +22,11 @@
klass.send :include, InstanceMethods
end
# Are we currently inside of an actor?
def actor?
- !!Thread.current[:actor]
+ !!Thread.current[:celluloid_actor]
end
# Generate a Universally Unique Identifier
def uuid
UUID.generate
@@ -53,11 +53,11 @@
# Shut down all running actors
def shutdown
Timeout.timeout(SHUTDOWN_TIMEOUT) do
actors = Actor.all
- Logger.info "Terminating #{actors.size} actors..." if actors.size > 0
+ Logger.debug "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
@@ -73,11 +73,11 @@
Actor.join(actor)
rescue DeadActorError, MailboxError
end
end
- Logger.info "Shutdown completed cleanly"
+ Logger.debug "Shutdown completed cleanly"
end
end
end
# Terminate all actors at exit
@@ -140,11 +140,11 @@
PoolManager.new_link(self, options)
end
# Run an actor in the foreground
def run(*args, &block)
- new(*args, &block).join
+ Actor.join(new(*args, &block))
end
# Trap errors from actors we're linked to when they exit
def exit_handler(callback = nil)
if callback
@@ -168,10 +168,14 @@
# Define the mailbox class for this class
def mailbox_class(klass)
@mailbox_factory = proc { klass.new }
end
+
+ def proxy_class(klass)
+ @proxy_factory = proc { klass }
+ end
# Define the default task type for this class
def task_class(klass = nil)
if klass
@task_class = klass
@@ -202,15 +206,26 @@
superclass.mailbox_factory
else
Mailbox.new
end
end
+
+ def proxy_factory
+ if defined?(@proxy_factory)
+ @proxy_factory.call
+ elsif superclass.respond_to?(:proxy_factory)
+ superclass.proxy_factory
+ else
+ nil
+ end
+ end
# Configuration options for Actor#new
def actor_options
{
:mailbox => mailbox_factory,
+ :proxy_class => proxy_factory,
:exit_handler => exit_handler,
:exclusive_methods => @exclusive_methods,
:task_class => task_class
}
end
@@ -237,18 +252,33 @@
# => #<WARNING: BARE CELLULOID OBJECT (Foo:0x3fefcb77c194)>
#
def bare_object; self; end
alias_method :wrapped_object, :bare_object
+ # Are we being invoked in a different thread from our owner?
+ def leaked?
+ @celluloid_owner != Thread.current[:celluloid_actor]
+ end
+
def inspect
- str = "#<#{Celluloid::BARE_OBJECT_WARNING_MESSAGE}(#{self.class}:0x#{object_id.to_s(16)})"
- ivars = instance_variables.map do |ivar|
- "#{ivar}=#{instance_variable_get(ivar).inspect}"
+ str = "#<"
+
+ if leaked?
+ str << Celluloid::BARE_OBJECT_WARNING_MESSAGE
+ else
+ str << "Celluloid::Actor"
end
- str << " " << ivars.join(' ') unless ivars.empty?
- str << ">"
+ str << "(#{self.class}:0x#{object_id.to_s(16)})"
+ str << " " unless instance_variables.empty?
+
+ instance_variables.each do |ivar|
+ next if ivar == Celluloid::OWNER_IVAR
+ str << "#{ivar}=#{instance_variable_get(ivar).inspect} "
+ end
+
+ str.sub!(/\s$/, '>')
end
# Process async calls via method_missing
def method_missing(meth, *args, &block)
# bang methods are async calls
@@ -256,11 +286,11 @@
unbanged_meth = meth.to_s.sub(/!$/, '')
args.unshift unbanged_meth
call = AsyncCall.new(:__send__, args, block)
begin
- Thread.current[:actor].mailbox << call
+ Thread.current[:celluloid_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
# async calls should find other ways to deal with actors dying
# during an async call (i.e. linking/supervisors)
@@ -288,21 +318,21 @@
raise AbortError.new(cause)
end
# Terminate this actor
def terminate
- Thread.current[:actor].terminate
+ Thread.current[:celluloid_actor].terminate
end
# Send a signal with the given name to all waiting methods
def signal(name, value = nil)
- Thread.current[:actor].signal name, value
+ Thread.current[:celluloid_actor].signal name, value
end
# Wait for the given signal
def wait(name)
- Thread.current[:actor].wait name
+ Thread.current[:celluloid_actor].wait name
end
# Obtain the current_actor
def current_actor
Actor.current
@@ -313,16 +343,16 @@
Actor.name
end
# Obtain the running tasks for this actor
def tasks
- Thread.current[:actor].tasks.to_a
+ Thread.current[:celluloid_actor].tasks.to_a
end
# Obtain the Celluloid::Links for this actor
def links
- Thread.current[:actor].links
+ Thread.current[:celluloid_actor].links
end
# Watch for exit events from another actor
def monitor(actor)
Actor.monitor(actor)
@@ -353,48 +383,48 @@
Actor.linked_to?(actor)
end
# Receive an asynchronous message via the actor protocol
def receive(timeout = nil, &block)
- actor = Thread.current[:actor]
+ actor = Thread.current[:celluloid_actor]
if actor
actor.receive(timeout, &block)
else
Thread.mailbox.receive(timeout, &block)
end
end
# Sleep letting the actor continue processing messages
def sleep(interval)
- actor = Thread.current[:actor]
+ actor = Thread.current[:celluloid_actor]
if actor
actor.sleep(interval)
else
Kernel.sleep interval
end
end
# Run given block in an exclusive mode: all synchronous calls block the whole
# actor, not only current message processing.
def exclusive(&block)
- Thread.current[:actor].exclusive(&block)
+ Thread.current[:celluloid_actor].exclusive(&block)
end
# Are we currently exclusive
def exclusive?
- actor = Thread.current[:actor]
+ actor = Thread.current[:celluloid_actor]
actor && actor.exclusive?
end
# Call a block after a given interval, returning a Celluloid::Timer object
def after(interval, &block)
- Thread.current[:actor].after(interval, &block)
+ Thread.current[:celluloid_actor].after(interval, &block)
end
# Call a block every given interval, returning a Celluloid::Timer object
def every(interval, &block)
- Thread.current[:actor].every(interval, &block)
+ Thread.current[:celluloid_actor].every(interval, &block)
end
# 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
@@ -405,21 +435,21 @@
end
# Handle async calls within an actor itself
def async(meth = nil, *args, &block)
if meth
- Actor.async Thread.current[:actor].mailbox, meth, *args, &block
+ Actor.async Thread.current[:celluloid_actor].mailbox, meth, *args, &block
else
- Thread.current[:actor].proxy.async
+ Thread.current[:celluloid_actor].proxy.async
end
end
# Handle calls to future within an actor itself
def future(meth = nil, *args, &block)
if meth
- Actor.future Thread.current[:actor].mailbox, meth, *args, &block
+ Actor.future Thread.current[:celluloid_actor].mailbox, meth, *args, &block
else
- Thread.current[:actor].proxy.future
+ Thread.current[:celluloid_actor].proxy.future
end
end
end
require 'celluloid/version'