lib/celluloid/actor.rb in celluloid-0.13.0.pre vs lib/celluloid/actor.rb in celluloid-0.13.0.pre2
- old
+ new
@@ -64,23 +64,11 @@
mailbox << call
rescue MailboxError
raise DeadActorError, "attempted to call a dead actor"
end
- 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[:celluloid_actor].handle_system_event(message)
- end
-
- response.value
- end
+ Celluloid.suspend(:callwait, call).value
end
# Invoke a method asynchronously on an actor via its mailbox
def async(mailbox, meth, *args, &block)
begin
@@ -166,11 +154,11 @@
@mailbox = options[:mailbox] || Mailbox.new
@exit_handler = options[:exit_handler]
@exclusives = options[:exclusive_methods]
@task_class = options[:task_class] || Celluloid.task_class
- @tasks = Set.new
+ @tasks = TaskSet.new
@links = Links.new
@signals = Signals.new
@receivers = Receivers.new
@timers = Timers.new
@running = true
@@ -306,19 +294,29 @@
# Schedule a block to run at the given time
def every(interval, &block)
@timers.every(interval) { task(:timer, &block) }
end
+ class Sleeper
+ def initialize(timers, interval)
+ @timers = timers
+ @interval = interval
+ end
+
+ def before_suspend(task)
+ @timers.after(@interval) { task.resume }
+ end
+
+ def wait
+ Kernel.sleep(@interval)
+ end
+ end
+
# Sleep for the given amount of time
def sleep(interval)
- task = Thread.current[:celluloid_task]
- if task && !Celluloid.exclusive?
- @timers.after(interval) { task.resume }
- Task.suspend :sleeping
- else
- Kernel.sleep(interval)
- end
+ sleeper = Sleeper.new(@timers, interval)
+ Celluloid.suspend(:sleeping, sleeper)
end
# Handle standard low-priority messages
def handle_message(message)
case message
@@ -388,11 +386,11 @@
task(:finalizer, :finalize) { @subject.finalize }
end
finalizer = @subject.class.finalizer
- if finalizer && @subject.respond_to?(finalizer)
+ if finalizer && @subject.respond_to?(finalizer, true)
task(:finalizer, :finalize) { @subject.__send__(finalizer) }
end
rescue => ex
Logger.crash("#{@subject.class}#finalize crashed!", ex)
end
@@ -413,10 +411,10 @@
Logger.crash("#{@subject.class}: CLEANUP CRASHED!", ex)
end
# Run a method inside a task unless it's exclusive
def task(task_type, method_name = nil, &block)
- if @exclusives && (@exclusives == :all || @exclusives.include?(method_name.to_sym))
+ if @exclusives && (@exclusives == :all || (method_name && @exclusives.include?(method_name.to_sym)))
exclusive { block.call }
else
@task_class.new(task_type, &block).resume
end
end