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