Project

General

Profile

« Previous | Next » 

Revision fd4ccbdd

Added by Marc Dequènes over 13 years ago

  • ID fd4ccbddaa0989a06add8eac41dba03823d784b2

[evol] preliminary work for Conversation synchronization in DSL (action callbacks had to be moved from Protocol to ConversationThread to be able to check idle with the new locks, needed to process notifications without falling idle)

View differences:

lib/cyborghood/cyborg/botnet_dsl.rb
@success_cb = nil
@calls = {}
@calls_reply = {}
@notifications = {}
@notifications_awaiting = 0
@notifications_received = 0
@final_reply = {
:results => {},
:errors => {}
:errors => {},
:notifications => {}
}
@notification_name = "task/#{@name}"
end
def on_error(&callback)
......
}
end
def send_notification(name, data)
name = @notification_name if name == :thread
Logger.instance.debug "Sending notification to '#{name}'"
@conversation.bot.get_channel(name) << data
end
# TODO: implement settable timeout
def wait_notification(name, criterias = {})
name = @notification_name if name == :thread
@notifications[name] ||= []
@notifications[name] << criterias
@notifications_awaiting += 1
end
protected
def _start_dsl
return if @calls.empty? and @notifications.empty?
@conversation.thread(@name) do |conv_thread|
conv_thread.lock(@name)
@calls.each_pair do |key, data|
conv_thread.call(data[:cmd], *data[:args]) do |reply|
@calls_reply[key] = reply[:status]
......
@final_reply[:errors][key] = reply[:exception]
end
check_finished
_check_finished(conv_thread)
end
end
@notifications.each_pair do |name, list|
subcription_id = @conversation.bot.get_channel(name).subscribe do |msg|
old_notifications_received = @notifications_received
list.each do |criterias|
if _notification_criterias_match(msg, criterias)
@final_reply[:notifications][name] ||= []
@final_reply[:notifications][name] << msg
@notifications_received += 1
# do not break, the same message may satisfy multiple criterias
end
end
if @final_reply[:notifications][name].size == @notifications[name].size
@conversation.bot.get_channel(name).unsubscribe(subcription_id)
end
_check_finished(conv_thread) if @notifications_received > old_notifications_received
end
end
end
end
def check_finished
return unless @calls.size == @calls_reply.size
def _notification_criterias_match(msg, criterias)
criterias.each_pair do |key, expected_val|
val = msg[key]
if expected_val.is_a? Regexp
return false if val !~ expected_val
else
return false if val != expected_val
end
end
true
end
def _check_finished(conv_thread)
return unless @calls.size == @calls_reply.size and
@notifications_received == @notifications_awaiting
conv_thread.unlock(@name)
# process reply in the same thread, but with a new DSL Thread context
cb = @calls_reply.values.index(:error) ? @error_cb : @success_cb

Also available in: Unified diff