Project

General

Profile

« Previous | Next » 

Revision d9694ad7

Added by Marc Dequènes almost 14 years ago

  • ID d9694ad7d8ecf4074becfbe41455a7d2535962ca

[evol] Botnet Conversation: created a new idle threads check (old method is pending for removal)

View differences:

lib/cyborghood/cyborg/conversation.rb
MAXIMUM_ERROR_COUNT = 3
MAXIMUM_LINES = 1024
attr_reader :bot, :peer_name, :peer_capabilities, :protocol
attr_reader :bot, :peer_name, :peer_capabilities, :protocol, :auto_close_threads
def initialize(bot, block = nil)
@bot = bot
......
@comm_stop = false
# associated conversation threads
@auto_close_threads = 60 # max idle time before closing (nil => never close threads)
@conv_threads = {}
@conv_threads_index = {}
@conv_threads_timers = {}
@conv_threads_closing = []
# thread 0 is reserved
@next_thread_id = 0
@system_thread = self.thread('system')
......
def receive_message(message)
logger.debug "Received message '#{message.action_code}' [#{identifier}]"
reset_idle_thread_check(message.conv_thread)
@protocol.process_received_message(message)
check_idle_thread(message.conv_thread)
end
def receive_error(msg)
......
# ignore mistakes
return unless @conv_threads.has_key? name
@conv_threads_closing << name
@conv_threads[name].close
# if only the system thread remains, notify idleness
......
@conv_threads_index.delete(th.id)
@conv_threads.delete(th.name)
@pending_thread_close.delete(th.name)
@conv_threads_closing.delete(th.name)
end
def send_message(message)
raise CyberError.new(:unrecoverable, "bot/conversation", "Cannot send message without action id") if message.action_id.nil?
reset_idle_thread_check(message.conv_thread)
flags = ""
flags += "+" unless message.action_parameters.nil?
......
message.action_parameters.to_yaml.each_line {|l| send_line l }
send_line EOD
end
check_idle_thread(message.conv_thread)
end
def identifier
......
th_name = msg[:thread]
close_thread(th_name) if @pending_thread_close.include? th_name
end
def reset_idle_thread_check(conv_thread)
return if @auto_close_threads.nil?
return if @conv_threads_closing.include? conv_thread.name
# ignore system thread
return if conv_thread.name == "system"
logger.debug "Thread '#{conv_thread.name}@#{@peer_name}' is working, canceling idle check"
# cancel time if exists
timer = @conv_threads_timers[conv_thread.id]
EventMachine.cancel_timer(timer) unless timer.nil?
@conv_threads_timers[conv_thread.id] = nil
end
def check_idle_thread(conv_thread)
return if @auto_close_threads.nil?
return if @conv_threads_closing.include? conv_thread.name
# ignore system thread
return if conv_thread.name == "system"
# if a timer is running, do nothing
return unless @conv_threads_timers[conv_thread.id].nil?
# test for idleness
return unless conv_thread.idle?
logger.debug "Thread '#{conv_thread.name}@#{@peer_name}' is currently idle, doing another check in #{@auto_close_threads}s"
# set timer for closing
@conv_threads_timers[conv_thread.id] = EventMachine.add_timer(@auto_close_threads) do
@conv_threads_timers[conv_thread.id] = nil
# if it is not idle, then do nothing, wait for another call to check_idle_thread
if conv_thread.idle?
logger.debug "Thread '#{conv_thread.name}@#{@peer_name}' is still idle, closing"
close_thread(conv_thread.name)
else
logger.debug "Thread '#{conv_thread.name}@#{@peer_name}' is no more idle"
end
end
end
end
end

Also available in: Unified diff