Revision cb79cd54
Added by Marc Dequènes about 14 years ago
- ID cb79cd54a913a92b6f4b610088b7c57406a9b7a5
lib/cyborghood/cyborg/conversation.rb | ||
---|---|---|
cb = @callbacks[message.action_id]
|
||
yield cb if block_given?
|
||
@callbacks.delete(message.action_id)
|
||
check_idle
|
||
cb
|
||
end
|
||
|
||
... | ... | |
|
||
def unlock(name)
|
||
@locks.delete(name)
|
||
check_idle
|
||
end
|
||
|
||
def locked?
|
||
not @locks.empty?
|
||
end
|
||
|
||
# check for known actions only, conversation API messages and
|
||
# attempts in error are not taken into account, that's why it is
|
||
# not sufficent to deduce idleness at connection level
|
||
def idle?
|
||
@callbacks.empty? and @locks.empty?
|
||
end
|
||
|
||
protected
|
||
|
||
def check_idle
|
||
return unless idle?
|
||
|
||
@conversation.bot.get_channel("peer/#{@conversation.identifier}/system") << {
|
||
:topic => 'THREAD IDLE',
|
||
:thread => @name
|
||
}
|
||
end
|
||
end
|
||
|
||
class Message
|
||
... | ... | |
|
||
@protocol = BotProtocol.new(self)
|
||
|
||
@pending_thread_close = Set.new
|
||
# we don't know the peer name yet
|
||
@system_notification_name = "peer/#{identifier}/system"
|
||
@system_notification = @bot.get_channel(@system_notification_name)
|
||
... | ... | |
@receive_error = true
|
||
end
|
||
|
||
# threads opened using the block variant are locked
|
||
# don't forget to unlock it when it is not needed anymore
|
||
def thread(name = 'default')
|
||
th = @conv_threads[name] || new_thread(name)
|
||
if block_given?
|
||
yield th
|
||
th.lock
|
||
|
||
# wait for end of chat
|
||
@pending_thread_close << name
|
||
yield th
|
||
else
|
||
th
|
||
end
|
||
... | ... | |
def delete_thread(th)
|
||
@conv_threads_index.delete(th.id)
|
||
@conv_threads.delete(th.name)
|
||
@pending_thread_close.delete(th.name)
|
||
@conv_threads_closing.delete(th.name)
|
||
end
|
||
|
||
... | ... | |
end
|
||
|
||
def process_system_notification(msg)
|
||
return unless msg[:topic] == 'THREAD IDLE'
|
||
|
||
th_name = msg[:thread]
|
||
close_thread(th_name) if @pending_thread_close.include? th_name
|
||
# TODO: process other things, like remote notifications
|
||
end
|
||
|
||
def reset_idle_thread_check(conv_thread)
|
||
... | ... | |
@conv_threads_timers[conv_thread.id] = nil
|
||
end
|
||
|
||
# check for idleness at connection level: not only actions done in a thread,
|
||
# but any communication through the thread (errors, protocol stuff, ...)
|
||
# that's why it is checked here and not in the ConversationThread class
|
||
def check_idle_thread(conv_thread)
|
||
return if @auto_close_threads.nil?
|
||
return if @conv_threads_closing.include? conv_thread.name
|
||
... | ... | |
return unless conv_thread.idle?
|
||
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
|
||
}
|
||
|
||
# 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
[evol] Botnet Conversation: removed old idle check mecanism while preserving notification