Project

General

Profile

« Previous | Next » 

Revision f6fd4b56

Added by Marc Dequènes about 14 years ago

  • ID f6fd4b56b4cf3ba6ea2d94485ead18cd4379fb3b

[evol] Task-based client DSL §5 (allow running subtasks in callbacks, implement 'meet' command, and fixed a race btw)

View differences:

bin/test_client
pp errors
pp results
# puts "Tadam: " + (ver1 == ver2 ? "same" : "different")
meet "waiter", :zzz
STDOUT.flush
on_success do
puts "OK compare stuff"
end
end
end
task "waiter" do
meet "compare stuff", :zzz
on_success do
puts "OK waiter"
end
end
lib/cyborghood/cyborg/dsl.rb
#++
require 'active_support/basic_object'
require 'set'
module CyborgHood
......
@errors = (previous_step_data[:errors] || {}).freeze
@results = (previous_step_data[:results] || {}).freeze
@dsl_runing = false
@subtasks = []
@cancel_on_start_error = false
@cancel_run = false
......
end
end
def meet(task_list, meetpoint, retry_time = 2)
task_list = [task_list] unless task_list.is_a? Array
task_list = Set.new(task_list)
notification_name = "meeting_point/#{meetpoint}"
notifications_received = Set.new
meet_ok = false
wait_notification(notification_name, {:topic => "MEET"}) do |subtask, msg|
notifications_received << msg[:from] if task_list.include?(msg[:from])
if task_list == notifications_received
meet_ok = true
subtask.finish
end
end
wait_timer(retry_time, true) do |subtask|
# in this order: send a last message before leaving
# (so we are sure the peer received a reply to its message)
send_notification notification_name, {:topic => "MEET", :from => @name}
subtask.finish if meet_ok
end
end
# error when adding subtasks, as we cannot check callbacks
# only applies to subsequently added tasks (wanted behavior)
def cancel_on_start_error
......
end
def _add_subtask(name, cb = nil, &block)
@subtasks << Subtask.new(self, name, &block)
subtask = Subtask.new(self, name, &block)
@subtasks << subtask
subtask.do_it if @dsl_runing
end
def _subtasks_finished?
......
def _check_finished
return unless _subtasks_finished?
# avoid race: no subtask will be run in this task now
@dsl_runing = false
next_step_data = {
:errors => {},
:results => {}
......
next_step_data[:results].merge!(subtask.results)
end
cb = next_step_data[:errors].empty? ? @error_cb : @success_cb
cb = next_step_data[:errors].empty? ? @success_cb : @error_cb
if cb
self.class.new(@bot, @name, next_step_data, &cb)
else
......
if @subtasks.empty?
_check_finished
else
@dsl_runing = true
@subtasks.each do |subtask|
# skip broken or canceled subtasks
next if subtask.finished?

Also available in: Unified diff