Ruby on rails RubyonRails:如何在多次请求中保持对象的活动性?

Ruby on rails RubyonRails:如何在多次请求中保持对象的活动性?,ruby-on-rails,ruby,Ruby On Rails,Ruby,当用户登录到我的网站时,我想打开与另一台服务器的连接。用户对我的服务器的请求将转换为对该服务器的读/写请求。只要用户登录,与该服务器的连接对象就应该是活动的,这样我就不需要在每次用户请求时重新连接 根据我对RubyonRails的理解,一旦请求完成,控制器/助手中的所有对象都会被清除。我需要在对不同控制器的多次请求中保持该对象的活动状态,直到用户注销 就架构而言,RoR框架中是否有任何地方可以放置此类对象?我倾向于使用具有类级方法或等于的帮助函数来设置连接,例如 def server_conne

当用户登录到我的网站时,我想打开与另一台服务器的连接。用户对我的服务器的请求将转换为对该服务器的读/写请求。只要用户登录,与该服务器的连接对象就应该是活动的,这样我就不需要在每次用户请求时重新连接

根据我对RubyonRails的理解,一旦请求完成,控制器/助手中的所有对象都会被清除。我需要在对不同控制器的多次请求中保持该对象的活动状态,直到用户注销


就架构而言,RoR框架中是否有任何地方可以放置此类对象?

我倾向于使用具有类级方法或等于的帮助函数来设置连接,例如

def server_connection
  @@connection ||= MyConnectionClass.new(variables, to, set, up, connection)
end
非常简单,现在您正在跨会话持久化连接,如果尚未设置连接,则进行设置(使用ruby的出色的
| |=
操作符)

编辑:刚刚意识到这是每个用户的,我可能只是修改我的当前版本,以包含一个基于用户id的哈希,该哈希存储连接,简单易行,只要记住在用户注销或空闲时间过长时关闭连接。对于一个小类来说,实际上封装它似乎是一个不错的选择

def server_connection(user)
  @@connection_hash ||= {}
  @@connection_hash[user.id] ||= MyConnectionClass.new(variables, to, set, up, connection, for user)
end

基本上,我认为你的问题的答案是否定的。有一些方法可以在请求之间为用户存储“基本”数据,无论是在DB、memcache或redis中,还是在类似的地方,但所有这些都最适合于可以干净地序列化的数据:数字、字符串,可能是以字符串形式存储的日期。但是,任何类型的网络连接都无法在请求之间可靠地序列化和反序列化,无论是到数据库还是其他网络资源(如外部web服务)


在不知道您想要保持开放的连接类型的任何细节的情况下,我认为您最好每次都从rails向该服务发出一个新的请求。如果是一个长请求,您可以做的一件事就是在后台进程中执行这些请求。然后,web客户端JS代码将发出初始请求,获取请求id,然后每隔几秒钟使用请求id ping rails应用程序,以查看响应是否就绪。准备好后,它可以读取响应等。这不会减少发出请求和获得响应的总时间,但它可以使页面对用户的响应性更强。

gem的“连接池”工作得很好

它允许您在客户端池中分布连接

您可以创建一个初始值设定项文件,它将在其中创建10个客户端来分发连接/工作。 config/initializers/connections.rb

$conn_pool = ConnectionPool::Wrapper.new(size: 10, timeout: 3) { 
   MyConnectionClass.new(my_conn_variables)
}
$conn_pool.send_to_my_server()
您可以像这样在代码中使用它。
app/helpers/my_helper.rb

$conn_pool = ConnectionPool::Wrapper.new(size: 10, timeout: 3) { 
   MyConnectionClass.new(my_conn_variables)
}
$conn_pool.send_to_my_server()

询问代码的问题必须证明对正在解决的问题的最低理解。包括尝试过的解决方案、它们不起作用的原因以及预期结果results@Monk_Code这不是一个代码问题;这更像是一个概念问题。他们的措辞可能会让人觉得他们是在要求编写代码,但更重要的是,他们要求如何(从概念上)在请求之间持久化Ruby对象。@user3545974如果每个请求都应该委托给另一台服务器,那么rails应用程序实际上在做什么?此外,我认为您不必担心在请求之间保持与另一台服务器的持久连接;允许连接像这样打开和关闭是正常的。在这方面,您是否关心一些事情?@PaulRichter不是每个请求都直接委托给该服务器,而是其中的许多请求。我的应用程序是该服务器功能和我自己功能的混合体。我认为保持持久的连接会更干净。但无论如何,即使我决定在每个请求上打开/关闭连接,是否有办法在请求之间保持RoR中的对象处于活动状态?@user3545974您需要某种持久内存缓存。看一看,它有一些链接到宝石正是为了这个目的。最终,它是一个后台进程,用于存储数据。我自己也用过redis。或者,作为一般建议,使用常规ActiveRecord机制将对象的数据存储在数据库中也是一个好主意;这样,如果存在多个异步请求的风险,您就不必担心过时的状态。这看起来像是建立了连接,但只针对处理请求的特定工作进程。如果您在多个(可能是虚拟的)服务器上平衡请求,那么其他工作者(比如unicorn)甚至线程都不会有相同的连接,更不用说其他web服务器了。@有趣的是,我认为这听起来不错。每个工作人员都有自己的连接,这会有点效率低下。这是一个遗憾,因为我喜欢这个解决方案的代码是多么简单和优雅:(它看起来确实很漂亮。您需要一个基本的
@@connection\u hash[user.id]。如果@connection\u hash[user.id],请断开连接。)
在注销时也是如此,这也很好,很简单,直到你不得不担心所有单独的工作人员都有各自的连接要断开……@sockmank完全正确,这就是为什么我有点不高兴发生这种情况。哦,好吧,这是一个有用的技巧,这基本上是ruby中的单例模式。这一点很好地指出了处理多线程环境需要更高级的单例模式。