Ruby IMAP IDLE 并发 - 如何解决?

发布于 2024-10-31 11:13:03 字数 1239 浏览 0 评论 0原文

我正在尝试构建一个(目前是私有的)Web 应用程序,该应用程序将利用 IMAP IDLE 连接在人们到达时显示电子邮件。

我很难弄清楚如何将其组合在一起 - 以及它如何与我的 Heroku RoR 服务器结合在一起。

我已经编写了一个用于连接到 IMAP 服务器并闲置的基本脚本,看起来像这样(简化):

imap = Net::IMAP.new server, port, usessl
imap.login username, password
imap.select "INBOX"

imap.add_response_handler do |response|
  if resp.kind_of(Net::IMAP::UntaggedResponse) && resp.name == "EXISTS"
    # New mail recieved. Ping back and process.
  end
end

imap.idle
loop do
  sleep 10*60
  imap.renew_idle
end

这将建立一个到 IMAP 服务器的连接并开始闲置。正如你所看到的,这是循环阻塞的。

我希望我的用户有多个 IMAP 连接同时处于空闲状态。最初,我只是想将它们每个都放在一个线程中,如下所示:

Thread.new do
  start_imap_idling(server, port, usessl, username, password)
end

我对线程还不是那么敏锐,但是使用这个解决方案,我仍然需要阻塞我的主线程来等待线程?因此,如果我这样做:

User.each do |user|
  Thread.new do
    start_imap_idling(server, port, usessl, username, password)
  end
end

loop do
  # Wait
end

那会起作用,但如果没有底部的循环来允许线程运行,就不行了?

我的问题是如何最好地将其与 Heroku 上的 Ruby On Rails 应用程序融合在一起?我不能用最后一个循环阻塞线程 - 那么我该如何运行它呢?另一个服务器?一个dyno more - 也许是一个工人?我一直在阅读一些有关事件机器的内容 - 这可以解决我的问题吗?如果可以,我应该如何写这个?

另一件事是,我希望能够添加新的 imap 客户端并动态删除当前的客户端。看起来怎么样?也许需要排队?

非常感谢任何帮助和评论!

I'm trying to build a (private, for now) web application that will utilize IMAP IDLE connections to show peoples emails as they arrive.

I'm having a hard time figuring out how to hack this together - and how it would fit together with my Heroku RoR server.

I've written a basic script for connecting to an IMAP server and idling, looks something like this (simplified):

imap = Net::IMAP.new server, port, usessl
imap.login username, password
imap.select "INBOX"

imap.add_response_handler do |response|
  if resp.kind_of(Net::IMAP::UntaggedResponse) && resp.name == "EXISTS"
    # New mail recieved. Ping back and process.
  end
end

imap.idle
loop do
  sleep 10*60
  imap.renew_idle
end

This will make one connection to the IMAP server and start idling. As you see, this is blocking with the loop.

I would like to have multiple IMAP connections idling at the same time for my users. Initially, I just wanted to put each of them in a thread, like so:

Thread.new do
  start_imap_idling(server, port, usessl, username, password)
end

I'm not that sharp on threads yet, but with this solution I will still have to block my main thread to wait for the threads? So if I do something like:

User.each do |user|
  Thread.new do
    start_imap_idling(server, port, usessl, username, password)
  end
end

loop do
  # Wait
end

That would work, but not without the loop at the bottom to allow the threads to run?

My question is how I best melt this together with my Ruby On Rails application on Heroku? I can't be blocking the thread with that last loop - so how do I run this? Another server? A dyno more - perhaps a worker? I've been reading a bit about Event Machine - could this solve my problem, if so, how should I go about writing this?

Another thing is, that I would like to be able to add new imap clients and remove current ones on the fly. How might that look? Something with a queue perhaps?

Any help and comments are very much appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

凉城 2024-11-07 11:13:03

我不熟悉 RoR、Event Machine 等的细节——但看起来你想设置一个生产者/消费者。

生产者是监听 IMAP 服务器更改的线程。当它收到更改时,会将它们写入队列。您似乎想要设置多个生成器,每个 IMAP 连接一个。

您的消费者是一个在从队列读取时阻塞的线程。当有东西进入队列时,它会解除阻塞并处理该事件。

然后你的主线程就可以自由地做任何你想做的事情。听起来您希望主线程执行诸如添加新的 IMAP 客户端(即生产者)和动态删除当前客户端之类的操作。

至于你在哪里运行这些东西:你可以在一个可执行文件中运行消费者和生产者,在同一台机器上的单独可执行文件中运行,或者在不同的机器上运行......这一切都取决于你的情况。

华泰

I'm not familiar with the specifics of RoR, Event Machine, etc. -- but it seems like you'd want to set up a producer/consumer.

The producer is your thread that's listening for changes from the IMAP server. When it gets changes it writes them to a queue. It seems like you'd want to set up multiple producers, one for each IMAP connection.

Your consumer is a thread that blocks on read from the queue. When something enters the queue it unblocks and processes the event.

Your main thread would then be free to do whatever you want. It sounds like you'd want your main thread doing things like adding new IMAP clients (i.e., producers) and removing current ones on the fly.

As for where you'd run these things: You could run the consumers and producer in one executable, in separate executables on the same machine, or on different machines... all depending upon your circumstances.

HTH

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文