lib/celluloid/actor.rb in celluloid-0.12.3 vs lib/celluloid/actor.rb in celluloid-0.12.4.pre

- old
+ new

@@ -19,10 +19,11 @@ super "caused by #{cause.inspect}: #{cause.to_s}" end end LINKING_TIMEOUT = 5 # linking times out after 5 seconds + OWNER_IVAR = :@celluloid_owner # reference to owning actor # Actors are Celluloid's concurrency primitive. They're implemented as # normal Ruby objects wrapped in threads which communicate with asynchronous # messages. class Actor @@ -41,18 +42,18 @@ Registry.root.clear end # Obtain the current actor def current - actor = Thread.current[:actor] + actor = Thread.current[:celluloid_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] + actor = Thread.current[:celluloid_actor] raise NotActorError, "not in actor scope" unless actor actor.name end # Invoke a method on the given actor via its mailbox @@ -63,19 +64,19 @@ mailbox << call rescue MailboxError raise DeadActorError, "attempted to call a dead actor" end - if Thread.current[:task] + if Thread.current[:celluloid_task] && !Celluloid.exclusive? Task.suspend(:callwait).value else response = loop do message = Thread.mailbox.receive do |msg| msg.respond_to?(:call) and msg.call == call end break message unless message.is_a?(SystemEvent) - Thread.current[:actor].handle_system_event(message) + Thread.current[:celluloid_actor].handle_system_event(message) end response.value end end @@ -101,48 +102,48 @@ # Obtain all running actors in the system def all actors = [] Thread.list.each do |t| - actor = t[:actor] + actor = t[:celluloid_actor] actors << actor.proxy if actor and actor.respond_to?(:proxy) end actors end # Watch for exit events from another actor def monitor(actor) raise NotActorError, "can't link outside actor context" unless Celluloid.actor? - Thread.current[:actor].linking_request(actor, :link) + Thread.current[:celluloid_actor].linking_request(actor, :link) end # Stop waiting for exit events from another actor def unmonitor(actor) raise NotActorError, "can't link outside actor context" unless Celluloid.actor? - Thread.current[:actor].linking_request(actor, :unlink) + Thread.current[:celluloid_actor].linking_request(actor, :unlink) end # Link to another actor def link(actor) monitor actor - Thread.current[:actor].links << actor + Thread.current[:celluloid_actor].links << actor end # Unlink from another actor def unlink(actor) unmonitor actor - Thread.current[:actor].links.delete actor + Thread.current[:celluloid_actor].links.delete actor end # Are we monitoring the given actor? def monitoring?(actor) actor.links.include? Actor.current end # Are we bidirectionally linked to the given actor? def linked_to?(actor) - monitoring?(actor) && Thread.current[:actor].links.include?(actor) + monitoring?(actor) && Thread.current[:celluloid_actor].links.include?(actor) end # Forcibly kill a given actor def kill(actor) actor.thread.kill @@ -161,10 +162,11 @@ # Wrap the given subject with an Actor def initialize(subject, options = {}) @subject = subject @mailbox = options[:mailbox] || Mailbox.new + @proxy_class = options[:proxy_class] || ActorProxy @exit_handler = options[:exit_handler] @exclusives = options[:exclusive_methods] @task_class = options[:task_class] || Celluloid.task_class @tasks = Set.new @@ -175,16 +177,17 @@ @running = true @exclusive = false @name = nil @thread = ThreadHandle.new do - Thread.current[:actor] = self - Thread.current[:mailbox] = @mailbox + Thread.current[:celluloid_actor] = self + Thread.current[:celluloid_mailbox] = @mailbox run end - @proxy = ActorProxy.new(self) + @proxy = @proxy_class.new(self) + @subject.instance_variable_set(OWNER_IVAR, self) end # Run the actor loop def run begin @@ -304,11 +307,12 @@ @timers.every(interval) { task(:timer, &block) } end # Sleep for the given amount of time def sleep(interval) - if task = Thread.current[:task] + task = Thread.current[:celluloid_task] + if task && !Celluloid.exclusive? @timers.after(interval) { task.resume } Task.suspend :sleeping else Kernel.sleep(interval) end @@ -343,10 +347,12 @@ end end # Handle exit events received by this actor def handle_exit_event(event) + @links.delete event.actor + # Run the exit handler if available return @subject.send(@exit_handler, event.actor, event.reason) if @exit_handler # Reraise exceptions from linked actors # If no reason is given, actor terminated cleanly @@ -364,11 +370,11 @@ # Handle cleaning up this actor after it exits def shutdown(exit_event = ExitEvent.new(@proxy)) run_finalizer cleanup exit_event ensure - Thread.current[:actor] = nil - Thread.current[:mailbox] = nil + Thread.current[:celluloid_actor] = nil + Thread.current[:celluloid_mailbox] = nil end # Run the user-defined finalizer, if one is set def run_finalizer return unless @subject.respond_to? :finalize