gpt4 book ai didi

ruby-on-rails - 在 Controller 操作之间共享一个 Net::IMAP 连接

转载 作者:数据小太阳 更新时间:2023-10-29 08:02:37 25 4
gpt4 key购买 nike

我只有一个 Controller 和其中的一些操作来处理与 IMAP 相关的不同功能。所以我的问题是我不想为每个 Action 创建一个单独的连接。例如在一个 Action 中我可以做类似的事情(它不是实际的代码):

def index
@imap = Net::IMAP.new(server, 993, true)
@imap.login(user, password)
@imap.select("INBOX")
end

再次在同一 Controller 内的另一个操作中,如果我需要做一些与 IMAP 相关的事情,那么我将不得不再次创建 @imap 变量。

我是第一次使用 IMAP,所以根据我的理解,每个操作中的 new 方法都会创建另一个到服务器的连接,我听说谷歌对 IMAP 的数量有连接限制(15)连接。

我无法序列化此连接对象或将其存储在 Redis 或 Memcached 等任何其他服务中或对其进行缓存,那么我如何创建一次此连接并在所有其他操作中使用它,如果可能的话至少在同一 Controller 中使用它?如果不可能,那么还有其他解决方案来处理这个问题吗?

当然,我可以从邮箱中缓存我需要的数据,但这没什么用,因为还有一些其他操作不需要数据,它需要在邮箱中执行一些操作,比如删除邮件,因此需要连接实例。

最佳答案

如何创建一个包装您的服务对象(单例)Net::IMAP。您可以将其粘贴到 app/services/imap_service.rb 或类似的地方。举个例子:

require 'singleton' # This is part of the standard library
require 'connection_pool' # https://github.com/mperham/connection_pool

class IMAPService
include Singleton

def initialize
@imap = ConnectionPool.new(size: 15) { Net::IMAP.new(server, 993, true) }
end

def inbox(user, password)
@imap.with do |conn|
conn.login(user, password)
conn.select("INBOX")
end
end
end

您可以像 IMAPService.instance 一样访问这个单例,例如IMAPService.instance.inbox(用户,密码)。我根据我们的讨论添加了 connect_pool gem,以确保这是线程安全的。 IMAPService 上没有attr_reader :imap。但是,如果您不想在此处包含所有必需的方法(尽管我建议尽可能使用服务对象),您可以添加一个以便可以在代码中直接访问连接池。然后你可以做 IMAPService.instance.imap.with { |conn| conn.login(user, password) 并且不需要依赖 IMAPService 中的方法。

值得注意的是,您不必使用 Singleton 混合宏。 Implementing "the lovely" Singleton 上有一篇非常好的文章这将向您展示两种方法。

关于ruby-on-rails - 在 Controller 操作之间共享一个 Net::IMAP 连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45102291/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com