lib/celluloid/actor.rb in celluloid-0.10.0 vs lib/celluloid/actor.rb in celluloid-0.11.0

- old
+ new

@@ -18,20 +18,27 @@ # Actors are Celluloid's concurrency primitive. They're implemented as # normal Ruby objects wrapped in threads which communicate with asynchronous # messages. class Actor extend Registry - attr_reader :proxy, :tasks, :links, :mailbox + attr_reader :subject, :proxy, :tasks, :links, :mailbox, :thread, :name class << self # Obtain the current actor def current actor = Thread.current[:actor] raise NotActorError, "not in actor scope" unless actor actor.proxy end - + + # Obtain the name of the current actor + def name + actor = Thread.current[:actor] + raise NotActorError, "not in actor scope" unless actor + actor.name + end + # Invoke a method on the given actor via its mailbox def call(mailbox, meth, *args, &block) call = SyncCall.new(Thread.mailbox, meth, args, block) begin @@ -85,24 +92,26 @@ # Wrap the given subject with an Actor def initialize(subject) @subject = subject @mailbox = subject.class.mailbox_factory - @proxy = ActorProxy.new(@mailbox, subject.class.to_s) @tasks = Set.new @links = Links.new @signals = Signals.new @receivers = Receivers.new @timers = Timers.new @running = true @exclusive = false + @name = nil - @thread = ThreadPool.get do + @thread = ThreadHandle.new do Thread.current[:actor] = self Thread.current[:mailbox] = @mailbox run end + + @proxy = ActorProxy.new(self) end # Is this actor running in exclusive mode? def exclusive? @exclusive @@ -143,10 +152,13 @@ begin message = @mailbox.receive(timeout) rescue ExitEvent => exit_event Task.new(:exit_handler) { handle_exit_event exit_event }.resume retry + rescue NamingRequest => ex + @name = ex.name + retry rescue TerminationRequest break end if message @@ -160,12 +172,13 @@ rescue MailboxShutdown # If the mailbox detects shutdown, exit the actor end shutdown - rescue => ex + rescue Exception => ex handle_crash(ex) + raise unless ex.is_a? StandardError end # How long to wait until the next timer fires def timeout i1 = @timers.wait_interval @@ -247,10 +260,11 @@ Thread.current[:mailbox] = nil end # Run the user-defined finalizer, if one is set def run_finalizer - @subject.finalize if @subject.respond_to? :finalize + return unless @subject.respond_to? :finalize + Task.new(:finalizer) { @subject.finalize }.resume rescue => ex Logger.crash("#{@subject.class}#finalize crashed!", ex) end # Clean up after this actor