多线程Sneaker中的对象变量就像一个全局可变数据



我有一个运动鞋工人(下面给出(作为聊天机器人的后端。

class RabbitMQWorker
include Sneakers::Worker
from_queue "message"
def work(options)
parsed_options = JSON.parse(options)
# Initializing some object variables
@question_id = parsed_options[:question_id]
@answer = parsed_option[:answer]
@session_id = parsed_option[:session_id]

ActiveRecord::Base.connection_pool.with_connection do
# send next question to the session_id based on answer
end
ack!
end
end

发生了什么

我在这里面临的问题是,当我用一个以上的线程运行sneaker,并且多个用户同时聊天时,稍晚发生的ampq事件会导致覆盖@session_id,因此,第二个用户得到两个问题,第一个用户没有得到任何问题。发生这种情况是因为当第一个事件开始处理时,第二个事件出现并覆盖@session_id。现在,当使用@session_id将下一个问题发送给第一个用户时,问题get将发送给第二个用户。

我的问题

  1. work方法和我在其中创建的任何instance variables是否像运动鞋线程的全局可变数据一样工作
  2. 如果是,那么我猜我需要将它们作为线程局部变量。如果我这样做了,那么我是否也需要在Rails逻辑的深处进行这些更改?因为这个工人使用Rails

好奇心问题

彪马是如何处理这些事情的?它是一个多线程应用程序服务器,我们在控制器中使用实例变量,它可以同时处理多个请求。这是否意味着彪马含蓄地处理了这种多重背景,而运动鞋却没有?

到目前为止我做了什么

  1. 我阅读了Sneaker的文档,找不到任何关于这方面的信息
  2. 我执行负载测试来验证问题,这就是我上面所说的问题
  3. 我试着弄清楚多线程实际上是如何工作的,但在任何地方都只有一般的东西。我在上面问的这个好奇的问题将有助于理清概念,我已经找了好几天了,但没有找到任何解释

在搜索了两天消息似乎混淆的问题后,我终于能够通过从我的工作人员中删除所有实例变量来解决这个问题。

这条线索给了我线索:https://github.com/jondot/sneakers/issues/244

也许我们应该简单地禁止worker中的实例变量,因为更改行为以实例化多个工作实例可能以某种方式破坏现有代码

和:

我认为每个线程一个实例是可行的。

因此,当您删除实例变量时,应该没问题!

最新更新