Project

General

Profile

« Previous | Next » 

Revision ad2ecdf4

Added by Marc Dequènes about 13 years ago

  • ID ad2ecdf474dddcb76fbf3ddb071fd41ab63fd4b7

[fix] IMAP: better handle IDLE sessions, process BYE messages from server, and add disconnection detection as Net::IMAP seems not to send BYE messages everytime it should

View differences:

lib/cyborghood-postman/imap.rb
@config = Config.instance
@imap = nil
@is_loggued = false
@need_reconnect = false
@available_mails = 0
@available_mails_mutex = Mutex.new
......
end
def connected?
not @imap.nil?
return false if @imap.nil?
return false if @need_reconnect
not @imap.disconnected?
end
def authenticate
......
def listen_to_events
@imap.add_response_handler do |resp|
logger.debug "IMAP event: " + resp.inspect if @config.debug.flags.include?('debug_imapverbose')
if resp.kind_of?(Net::IMAP::UntaggedResponse) and resp.name == "EXISTS"
@available_mails_mutex.synchronize do
@available_mails = resp.data.to_i
logger.debug "*** Received new mails (#{@available_mails})" if @available_mails > 0
if resp.kind_of?(Net::IMAP::UntaggedResponse)
case resp.name
when "EXISTS"
@available_mails_mutex.synchronize do
@available_mails = resp.data.to_i
logger.debug "*** Received new mails (#{@available_mails})" if @available_mails > 0
end
when "BYE"
@need_reconnect = true
logger.debug "IMAP reconnection needed"
end
end
end
......
if self.capabilities.include?("IDLE")
logger.debug "Waiting for new mails in idle mode"
@imap.idle
sleep(1) until @stop_mail_check or waiting_mails?
@imap.idle_done
until @stop_mail_check
return if @imap.nil? or not connected?
@imap.idle
# restart IDLE after 5 min
t = Time.now.to_i
sleep(1) until Time.now.to_i - t >= 300 or @stop_mail_check or waiting_mails?
@imap.idle_done
end
end
end
end
......
t2 = Time.now.to_i
sleep_time = @min_check_interval - (t2 - t)
rescue SocketError, Errno::EPIPE, Errno::ECONNREFUSED, Errno::ETIMEDOUT, Errno::ENETUNREACH => e
rescue SocketError, Errno::EPIPE, Errno::ECONNREFUSED, Errno::ETIMEDOUT, Errno::ENETUNREACH, IOError => e
logger.warn "Network error: " + e.message.strip
sleep_time = @min_check_interval
end
......
end
def check_inbox(&message_handler)
return unless @imap
logger.debug "Examining INBOX"
@imap.select('INBOX')
......
return unless @imap
begin
@imap.logout if @is_loggued
unless @imap.disconnected?
@imap.logout if @is_loggued
logger.debug "Disconnecting from IMAP server..."
@imap.disconnect
logger.debug "Disconnected from IMAP server"
logger.debug "Disconnecting from IMAP server..."
@imap.disconnect
logger.debug "Disconnected from IMAP server"
end
rescue IOError
logger.debug "Already diconnected from IMAP server"
logger.debug "Already disconnected from IMAP server"
ensure
@imap = nil
@is_loggued = false
@imap_capab = nil
@need_reconnect = false
end
end
end

Also available in: Unified diff