Project

General

Profile

« Previous | Next » 

Revision 67e8f239

Added by Marc Dequènes about 14 years ago

  • ID 67e8f239f9770df6a75d9ba4fb612f5283df8bd6

[evol] client DSL: reorganized notification code and move 'acts' (currently sending notifies) in the _start_dsl call

View differences:

lib/cyborghood/cyborg/botnet_dsl.rb
@success_cb = nil
@calls = {}
@calls_reply = {}
@notifications = {}
@notifications_awaiting = 0
@notifications_received = 0
@in_notifications = {}
@in_notifications_awaiting = 0
@in_notifications_received = 0
@out_notifications = {}
@final_reply = {
:results => {},
......
def send_notification(name, data)
name = @notification_name if name == :thread
Logger.instance.debug "Sending notification to '#{name}'"
@conversation.bot.get_channel(name) << data
@out_notifications[name] ||= []
@out_notifications[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
@in_notifications[name] ||= []
@in_notifications[name] << criterias
@in_notifications_awaiting += 1
end
protected
def _has_events?
not @calls.empty? or not @in_notifications.empty?
end
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]
case reply[:status]
when :ok
@final_reply[:results][key] = reply[:result]
when :decline
# TODO: remove this case ???
when :error
@final_reply[:errors][key] = reply[:exception]
end
if _has_events?
@conversation.thread(@name) do |conv_thread|
conv_thread.lock(@name)
_waiting_events(conv_thread)
end
end
_check_finished(conv_thread)
_acts
end
def _waiting_events(conv_thread)
@calls.each_pair do |key, data|
conv_thread.call(data[:cmd], *data[:args]) do |reply|
@calls_reply[key] = reply[:status]
case reply[:status]
when :ok
@final_reply[:results][key] = reply[:result]
when :decline
# TODO: remove this case ???
when :error
@final_reply[:errors][key] = reply[:exception]
end
_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
@in_notifications.each_pair do |name, list|
subcription_id = @conversation.bot.get_channel(name).subscribe do |msg|
old_notifications_received = @in_notifications_received
list.each do |criterias|
if _notification_criterias_match(msg, criterias)
@final_reply[:notifications][name] ||= []
@final_reply[:notifications][name] << msg
@in_notifications_received += 1
# do not break, the same message may satisfy multiple criterias
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
if @final_reply[:notifications][name].size == @in_notifications[name].size
@conversation.bot.get_channel(name).unsubscribe(subcription_id)
end
_check_finished(conv_thread) if @in_notifications_received > old_notifications_received
end
end
end
def _acts
@in_notifications.each_pair do |name, list|
chan = @conversation.bot.get_channel(name)
list.each do |data|
chan << data
end
end
end
......
true
end
def _finished?
@calls.size == @calls_reply.size and
@in_notifications_received == @in_notifications_awaiting
end
def _check_finished(conv_thread)
return unless @calls.size == @calls_reply.size and
@notifications_received == @notifications_awaiting
return unless _finished?
conv_thread.unlock(@name)

Also available in: Unified diff