Project

General

Profile

Bug #10031

Net::IMAP idle can still block a thread forever.

Added by James Pike almost 2 years ago. Updated 6 months ago.

Status:
Closed
Priority:
Normal
Assignee:
ruby -v:
ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-linux]
[ruby-core:63693]

Description

When calling Net::IMAP idle often errors will go unnoticed forever, simply leaving the Thread that called "idle" blocking forever.

For example try bringing your internet connection down whilst a thread is calling the idle method, the calling thread will now be blocked forever.

I've encountered this issue also without losing my internet connection, sometimes the remote server will disconnect the client and the client will never notice leading to the same issue.

Associated revisions

Revision 52216
Added by Shugo Maeda 6 months ago

  • lib/net/imap (idle): add a new argument timeout for keep-alive. [Bug #10031]

Revision 52216
Added by Shugo Maeda 6 months ago

  • lib/net/imap (idle): add a new argument timeout for keep-alive. [Bug #10031]

History

#1 [ruby-core:63695] Updated by Eric Wong almost 2 years ago

Setting SO_KEEPALIVE on the socket will help, but that still takes at
least 2 hours to detect on a stock Linux system. Do you want to set a
shorter keepalive, or is ~2 hours OK?

You can change the interval using OS-specific knobs (e.g. sysctl).

Totally untested one line patch here:

--- a/lib/net/imap.rb
+++ b/lib/net/imap.rb
@@ -1053,6 +1053,7 @@ module Net
       @tagno = 0
       @parser = ResponseParser.new
       @sock = TCPSocket.open(@host, @port)
+      @sock.setsockopt(:SOL_SOCKET, :SO_KEEPALIVE, 1)
       begin
     if options[:ssl]
       start_tls_session(options[:ssl])

#2 [ruby-core:63788] Updated by Shugo Maeda almost 2 years ago

  • Status changed from Open to Assigned
  • Assignee set to Shugo Maeda

#3 Updated by Shugo Maeda 6 months ago

  • Status changed from Assigned to Closed

Applied in changeset r52216.


  • lib/net/imap (idle): add a new argument timeout for keep-alive. [Bug #10031]

#4 [ruby-core:71150] Updated by Shugo Maeda 6 months ago

I've added a new argument timeout for Net::IMAP#idle to solve this problem.

For example, the following code checks the connection for each 60 seconds.

loop do
  imap.idle(60) do |res|
    ...
  end
end

Also available in: Atom PDF