Revision 4d9f2962
Added by Marc Dequènes about 14 years ago
- ID 4d9f2962db882142ce63530d9b8844890bb557be
bin/test_client | ||
---|---|---|
$: << File.join(File.dirname(__FILE__), "..", "lib")
|
||
|
||
require 'cyborghood/cyborg'
|
||
require 'cyborghood/cyborg/dsl'
|
||
|
||
|
||
module CyborgHood
|
||
... | ... | |
# to test the closure through the inner instance_eval calls
|
||
toto = true
|
||
|
||
# task "compare stuff" do
|
||
c = 0
|
||
task "compare stuff" do
|
||
# ask :MapMaker, :ver1, "/api_version"
|
||
# ask :Librarian, :ver2, "/api_version"
|
||
# on_error do
|
||
# puts "PLOUF"
|
||
# pp reply
|
||
# end
|
||
# on_success do
|
||
# puts "OK"
|
||
# pp reply
|
||
wait_notification :thread, {:topic => "HELOz"}, 5 do |subtask, msg|
|
||
puts "POUET NOTIF"
|
||
subtask.finish
|
||
end
|
||
send_notification :thread, {:topic => "HELO"}
|
||
wait_timer 2, true do |subtask|
|
||
c += 1
|
||
puts "TIMER !!!"
|
||
STDOUT.flush
|
||
subtask.finish if c == 10
|
||
end
|
||
on_error do
|
||
puts "PLOUF"
|
||
pp errors
|
||
pp results
|
||
end
|
||
on_success do
|
||
puts "OK"
|
||
pp errors
|
||
pp results
|
||
# puts "Tadam: " + (ver1 == ver2 ? "same" : "different")
|
||
# end
|
||
# end
|
||
end
|
||
end
|
||
|
||
conversation_with "MapMaker" do
|
||
on_error do
|
lib/cyborghood/cyborg.rb | ||
---|---|---|
logger.info "Bot starting"
|
||
EventMachine.run do
|
||
start_work
|
||
try_stop
|
||
end
|
||
rescue EventMachine::ConnectionNotBound
|
||
logger.fatal "Internal error (EventMachine::ConnectionNotBound)"
|
||
... | ... | |
end
|
||
|
||
def ready_to_stop?
|
||
true
|
||
DSL::Task.idle?
|
||
end
|
||
|
||
def stop
|
||
... | ... | |
[]
|
||
end
|
||
|
||
def task(name, &block)
|
||
DSL::Task.new(self, name, &block)
|
||
end
|
||
|
||
def schedule_task(callback, &task)
|
||
EventMachine.defer(task, callback)
|
||
end
|
lib/cyborghood/cyborg/botnet.rb | ||
---|---|---|
end
|
||
|
||
def ready_to_stop?
|
||
@comm_list.empty?
|
||
@comm_list.empty? and super
|
||
end
|
||
end
|
||
end
|
lib/cyborghood/cyborg/dsl.rb | ||
---|---|---|
|
||
|
||
module CyborgHood
|
||
module BotnetDSL
|
||
module DSL
|
||
class BaseDSL < ActiveSupport::BasicObject
|
||
def initialize(&block)
|
||
self.instance_eval(&block)
|
||
_start_dsl
|
||
end
|
||
|
||
reveal logger
|
||
reveal :class
|
||
reveal :logger
|
||
end
|
||
|
||
class Task < BaseDSL
|
||
attr_reader :bot, :errors, :results
|
||
attr_reader :bot, :name, :errors, :results
|
||
|
||
@@task_list = {}
|
||
@@task_wip = 0
|
||
|
||
def self.idle?
|
||
@@task_wip == 0
|
||
end
|
||
|
||
def initialize(bot, name = nil, previous_step_data = {}, &block)
|
||
@bot = bot
|
||
@name = name
|
||
|
||
@@task_list[@name] = self unless @name.nil?
|
||
@@task_wip += 1
|
||
|
||
@errors = (previous_step_data[:errors] || {}).freeze
|
||
@results = (previous_step_data[:results] || {}).freeze
|
||
... | ... | |
begin
|
||
super(&block)
|
||
rescue
|
||
logger.error "Task '#{@name}': could not initialize DSL: " + $!.to_s
|
||
logger.error "Task '#{@name}': error in DSL: " + $!.to_s
|
||
logger.debug $!.backtrace.join("\n")
|
||
@cancel_run = true
|
||
end
|
||
... | ... | |
|
||
def task(name = nil, &block)
|
||
_add_subtask("task/#{name}") do |subtask|
|
||
self.class.new(name || @name, &block)
|
||
self.class.new(@bot, name || @name, &block)
|
||
subtask.finish
|
||
end
|
||
end
|
||
... | ... | |
attr_reader :name
|
||
attr_accessor :results, :errors
|
||
|
||
def initialize(name, &block)
|
||
def initialize(task, name, &block)
|
||
@task = task
|
||
@name = name
|
||
@block = block
|
||
|
||
... | ... | |
def do_it
|
||
@block.call self
|
||
rescue
|
||
msg = "Task '#{@name}': error: " + $!.to_s
|
||
msg = "Task '#{@task.name}': error: " + $!.to_s
|
||
logger.error msg
|
||
@errors << CyberError.new(:unrecoverable, "botnet/client/dsl", msg)
|
||
logger.debug $!.backtrace.join("\n")
|
||
finish
|
||
end
|
||
|
||
def finish
|
||
if @finished
|
||
raise CyberError.new(:unrecoverable, "botnet/client/dsl", "Task '#{@name}': subtask should have ended, but it lied")
|
||
raise CyberError.new(:unrecoverable, "botnet/client/dsl", "Task '#{@task.name}': subtask should have ended, but it lied")
|
||
end
|
||
@finished = true
|
||
logger.debug "Task '#{@task.name}': subtask '#{@name}' finished"
|
||
@task.__send__(:_check_finished)
|
||
end
|
||
|
||
def finished?
|
||
... | ... | |
end
|
||
|
||
def _add_subtask(name, cb = nil, &block)
|
||
@subtasks << Subtask.new(name, &block)
|
||
@subtasks << Subtask.new(self, name, &block)
|
||
end
|
||
|
||
def _subtasks_finished?
|
||
... | ... | |
return unless _subtasks_finished?
|
||
|
||
next_step_data = {
|
||
:errors = {},
|
||
:results = {}
|
||
:errors => {},
|
||
:results => {}
|
||
}
|
||
|
||
@subtasks.each do |subtask|
|
||
next_step_data[:errors][subtask.name] = subtask.errors
|
||
next_step_data[:errors][subtask.name] = subtask.errors unless subtask.errors.empty?
|
||
next_step_data[:results].merge!(subtask.results)
|
||
end
|
||
|
||
cb = next_step_data[:errors].empty? ? @error_cb : @success_cb
|
||
self.class.new(name || @name, next_step_data, &cb) if cb
|
||
if cb
|
||
self.class.new(@bot, @name, next_step_data, &cb)
|
||
else
|
||
logger.debug "Task '#{@name}': finished"
|
||
end
|
||
|
||
@@task_wip -= 1
|
||
end
|
||
|
||
def _notification_criterias_match(msg, criterias)
|
||
... | ... | |
def _start_dsl
|
||
return false if @cancel_run
|
||
|
||
@subtasks.each do |subtask|
|
||
# skip broken or canceled subtasks
|
||
next if subtask.finished?
|
||
subtask.do_it
|
||
logger.debug "Task '#{@name}': begining step"
|
||
|
||
if @subtasks.empty?
|
||
_check_finished
|
||
else
|
||
@subtasks.each do |subtask|
|
||
# skip broken or canceled subtasks
|
||
next if subtask.finished?
|
||
subtask.do_it
|
||
end
|
||
end
|
||
|
||
true
|
Also available in: Unified diff
[evol] Task-based client DSL §4 (many fixes, helper, bot stop condition, more logging)