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'