Revision a089227c
Added by Marc Dequènes almost 14 years ago
- ID a089227ca94121115f46e5998b497fa102787398
lib/cyborghood/cyborg/botnet/conversation.rb | ||
---|---|---|
@sent
|
||
end
|
||
|
||
def send
|
||
def send(go_quiet = false)
|
||
raise CyberError.new(:unrecoverable, "bot/conversation", "Not sending twice the same message") if self.sent?
|
||
@action_id = @conv_thread.next_action_id if @action_id.nil?
|
||
@conv_thread.conversation.send_message(self)
|
||
@conv_thread.conversation.send_message(self, go_quiet)
|
||
@sent = true
|
||
|
||
# return message (convenience)
|
||
... | ... | |
@split_data_message = nil
|
||
@split_data = []
|
||
@comm_stop = false
|
||
@comm_dead = false
|
||
|
||
# associated conversation threads
|
||
@auto_close_threads = 60 # max idle time before closing (nil => never close threads)
|
||
... | ... | |
@next_thread_id = 0
|
||
@system_thread = self.thread('system')
|
||
|
||
@stop_when_finished = false
|
||
|
||
# post-negociation peer info
|
||
@peer_name = nil
|
||
@peer_capabilities = []
|
||
... | ... | |
|
||
def unbind
|
||
logger.info "Conversation finished with #{identifier} (#{@peer_name})"
|
||
|
||
# ensure we go quiet
|
||
@message_send.synchronize do
|
||
@comm_stop = true
|
||
end
|
||
@comm_dead = true
|
||
|
||
@bot.unregister_communication @peer_name unless @peer_name.nil?
|
||
@bot.drop_channel(@system_notification_name)
|
||
|
||
@conv_threads.each_value {|s| s.close(false) }
|
||
@conv_threads = {}
|
||
@conv_threads_index = {}
|
||
|
||
@comm_logic_block.call false unless @comm_logic_block.nil? or @protocol.negociation_ok?
|
||
end
|
||
|
||
def usuable?
|
||
not (@comm_dead or @comm_stop)
|
||
end
|
||
|
||
def bye
|
||
@protocol.send_quit_leaving
|
||
stop :quickly
|
||
end
|
||
|
||
def stop(condition)
|
||
case condition
|
||
when :when_finished
|
||
@stop_when_finished = true
|
||
when :quickly
|
||
@protocol.send_quit_leaving
|
||
end
|
||
end
|
||
|
||
def set_peer_info(name, capabilities)
|
||
... | ... | |
end
|
||
|
||
def set_comm_stop(peer_left = false)
|
||
@comm_stop = true
|
||
return if @comm_stop
|
||
|
||
logger.debug "Conversation with '#{@peer_name}' on #{identifier} is closing"
|
||
@system_notification.unsubscribe(@system_notification_processing)
|
||
|
||
# the block may use a <message>.send(true) to go quiet (set @comm_stop)
|
||
yield if block_given?
|
||
|
||
# ensure we go quiet
|
||
@message_send.synchronize do
|
||
@comm_stop = true
|
||
end
|
||
|
||
peer_left ? close_connection : close_connection_after_writing
|
||
end
|
||
|
||
... | ... | |
@conv_threads_closing.delete(th.name)
|
||
end
|
||
|
||
def send_message(message)
|
||
def send_message(message, quiet_after = false)
|
||
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 += "+" unless message.action_parameters.nil?
|
||
|
||
@message_send.synchronize do
|
||
send_line sprintf("%s-%04d-%04d%s %s", @bot.name, message.conv_thread.id, message.action_id, flags, message.action_code)
|
||
unless message.action_parameters.nil?
|
||
message.action_parameters.to_yaml.each_line {|l| send_line l }
|
||
send_line EOD
|
||
unless @comm_stop
|
||
send_line sprintf("%s-%04d-%04d%s %s", @bot.name, message.conv_thread.id, message.action_id, flags, message.action_code)
|
||
unless message.action_parameters.nil?
|
||
message.action_parameters.to_yaml.each_line {|l| send_line l }
|
||
send_line EOD
|
||
end
|
||
|
||
@comm_stop = true if quiet_after
|
||
end
|
||
end
|
||
|
||
... | ... | |
|
||
def send_line(msg)
|
||
return if error?
|
||
return if @comm_stop
|
||
|
||
logger.debug "Sending data [#{identifier}]: #{msg}"
|
||
send_data "#{msg}\n"
|
||
... | ... | |
@conv_threads_timers_manage.synchronize do
|
||
# if a timer is running, do nothing
|
||
return unless @conv_threads_timers[conv_thread.id].nil?
|
||
end
|
||
|
||
# test for idleness
|
||
if conv_thread.idle?
|
||
logger.debug "Thread '#{conv_thread.name}@#{@peer_name}' is currently idle, doing another check in #{@auto_close_threads}s"
|
||
# test for idleness
|
||
if conv_thread.idle?
|
||
if @stop_when_finished
|
||
logger.debug "Thread '#{conv_thread.name}@#{@peer_name}' is currently idle, considered finished, closing"
|
||
close_thread(conv_thread.name)
|
||
return
|
||
end
|
||
|
||
logger.debug "Thread '#{conv_thread.name}@#{@peer_name}' is currently idle, doing another check in #{@auto_close_threads}s"
|
||
|
||
# send notification
|
||
@bot.get_channel(@system_notification_name) << {
|
||
:topic => 'THREAD IDLE',
|
||
:thread => conv_thread.name
|
||
}
|
||
# send notification
|
||
@bot.get_channel(@system_notification_name) << {
|
||
:topic => 'THREAD IDLE',
|
||
:thread => conv_thread.name
|
||
}
|
||
|
||
@conv_threads_timers_manage.synchronize do
|
||
# set timer for closing
|
||
@conv_threads_timers[conv_thread.id] = EventMachine.add_timer(@auto_close_threads) do
|
||
@conv_threads_timers[conv_thread.id] = nil
|
Also available in: Unified diff
[fix/evol] work on better Interface/Task/Conversation/… sync and bot stop action in order to avoid races and locks