【发布时间】:2016-07-14 20:16:54
【问题描述】:
我正在使用 Ruby 编写一个从 IMAP 服务器同步邮件的守护进程。我有多个帐户,我一个接一个地登录并下载未读消息。但是,我无法重用与 IMAP 服务器的现有连接。
这是我想要做的一个粗略的例子:
require 'net/imap'
imap = Net::IMAP.new('imap.example.com')
imap.login('login@example.com', 'R2D2C3PO')
imap.select('INBOX')
# interacting with the server, like fetching the messages etc.
# for example:
puts imap.fetch(3, "BODYSTRUCTURE")
# now I want to log out of the account and log in with another
imap.logout
imap.login('anotherlogin@example.com', 'R2D2C3PO')
imap.select('INBOX')
# again - interacting with the server
puts imap.fetch(3, "BODYSTRUCTURE")
imap.disconnect
但是调用logout 方法时会引发异常:
/usr/local/rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/monitor.rb:110:in `sleep': No live threads left. Deadlock? (fatal)
from /usr/local/rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/monitor.rb:110:in `wait'
from /usr/local/rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/monitor.rb:110:in `wait'
from /usr/local/rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/net/imap.rb:1166:in `get_tagged_response'
from /usr/local/rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/net/imap.rb:1225:in `block in send_command'
from /usr/local/rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/monitor.rb:211:in `mon_synchronize'
from /usr/local/rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/net/imap.rb:1207:in `send_command'
from /usr/local/rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/net/imap.rb:435:in `login'
from test.rb:13:in `<main>'
我完全被线程异常弄糊涂了,因为守护进程只是单线程的。在引擎盖下,进程在等待服务器响应时挂在条件变量上。为什么调用之前的方法(LOGIN、SELECT等命令)没有问题,而发送LOGOUT命令时却出现问题?
编辑:
不知何故,我完全错过了这样一个事实,即LOGOUT 命令使与 IMAP 服务器的连接不再可用(正如@HolgerJust 指出的那样)。虽然我重用连接的想法惨遭失败,但重点仍然存在:发送LOGOUT 命令时引发异常,此时仍是合法操作,不应造成任何麻烦。
【问题讨论】:
-
您的问题似乎是“登录”,而不是“注销”。
-
我非常怀疑
LOGIN命令有问题,因为在第一次登录后,我可以毫不费力地下载所有邮件。 -
对不起,我完全误解了你。是的,这确实是
LOGIN命令的问题。不知何故,我一直坚信问题出在LOGOUT命令上。我不知道为什么。