EventMachine几乎没有捕获同时发生的事件

时间:2014-01-14 00:58:14

标签: ruby concurrency imap eventmachine

我正在使用EventMachine处理传入的电子邮件,这些电子邮件有时可能会非常高。到目前为止,我所拥有的代码肯定适用于相隔至少约5秒的电子邮件,但在此之下的某个地方,只有一封电子邮件将被处理,但是很多邮件都会到达。我曾尝试在几个不同的地方添加EM.defer语句,我认为这会有所帮助,但无济于事。我还应该注意,如果它有任何区别,我也在这个例子中使用了em-imap gem。

代码的相关部分在这里:

EM.run do

client = EM::IMAP.new('imap.gmail.com', 993, true)
client.connect.bind! do
  client.login('me@email.com', 'password123')
end.bind! do
  client.select('INBOX')
end.bind! do
  client.wait_for_new_emails do |response|
    client.fetch(response.data).callback do |fetched|
        currentSubjectLine = fetched.first.attr.values[1].subject
        desiredCommand = parseSubjectLine(currentSubjectLine)
        if desiredCommand == 0
            if fetched.first.attr.values[0].parts.length == 2
                if fetched.first.attr.values[0].parts[1].subtype.downcase != "pdf"
                    puts 'Error: Missing attachment, or attachment of the wrong type.'
                else
                    file_name = fetched.first.attr.values[0].parts[1].param.values[0]
                    client.fetch(response.data, "BODY[2]").callback do |attachments|
                        attachment = attachments[0].attr["BODY[2]"]                         
                        File.new(file_name,'wb+').write(Base64.decode64(attachment))
                    end
                end...

我是否以某种方式阻止了此代码段中的反应堆?我正在使用的某些库是否可能不合适? GMail的IMAP服务器可以与它有关吗?在您可以自信地回答之前,您是否还需要有关某些情况下会发生什么的更多信息?一如既往,非常感谢任何帮助。谢谢!

使用最小化代码进行更新

万一我的组织中的任何内容都与它有关,我会包含我认为可能相关的所有内容。

module Processing

  def self.run
    EM.run do
        client = EM::IMAP.new('imap.gmail.com', 993, true)
        client.connect.bind! do
          client.login('me@email.com', 'password123')
        end.bind! do
          client.select('INBOX')
        end.bind! do
          client.wait_for_new_emails do |response|
            client.fetch(response.data).callback do |fetched|
                 puts fetched[0].attr.values[1].subject
            end
          end

        end.errback do |error|
          puts "Something failed: #{error}"
        end
    end...

Processing.run

1 个答案:

答案 0 :(得分:0)

不要因为这样说而讨厌我,而是重构那个使得Demeter抽搐成可读的错误的金字塔,这个错误将会显露出来:)

如果它没有显示出来,您将能够将其归结为最简单的代码,以再现问题并将其作为问题提交给https://github.com/eventmachine/eventmachine

然而,EM不再受支持了,开发人员有点大胆,所以考虑转移到https://github.com/celluloid/celluloidhttps://github.com/celluloid/celluloid-io

<强> PS

刚看到这个

File.new(file_name,'wb+').write(Base64.decode64(attachment))

是一个阻止呼叫afaik,试着玩这个,你可能能够重现这个问题。有关解决此问题的可能方法,请参阅https://github.com/martinkozak/em-fileshttp://eventmachine.rubyforge.org/EventMachine.html#defer-class_method