Project

General

Profile

« Previous | Next » 

Revision 4d9f2962

Added by Marc Dequènes about 14 years ago

  • ID 4d9f2962db882142ce63530d9b8844890bb557be

[evol] Task-based client DSL §4 (many fixes, helper, bot stop condition, more logging)

View differences:

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