1

我有一个运动鞋工人(如下所示)作为聊天机器人的后端。

  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

发生了什么

我在这里面临的问题是,当我运行超过 1 个线程的运动鞋并且多个用户同时聊天时,稍后出现的 ampq 事件会导致覆盖,@session_id因此,第二个用户会收到两个问题第一个没有。发生这种情况是因为当第一个事件正在处理时,第二个事件来了并覆盖了@session_id。现在,当需要使用@session_id 将下一个问题发送给第一个用户时,问题就会发送给第二个用户。

我的问题

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

好奇心问题

彪马是如何管理这些事情的?它是一个多线程的应用服务器,我们在控制器中使用实例变量,它可以同时处理多个请求。这是否意味着 Puma 隐含地处理这种多上下文而 Sneakers 没有?

到目前为止我所做的

  1. 我阅读了Sneaker的文档,但没有找到任何关于此的内容。
  2. 我执行负载测试来验证问题,这就是我上面所说的问题。
  3. 我试着让我的逻辑清楚多线程实际上是如何工作的,但到处都是一般的东西。我上面提出的好奇心问题将有助于清除概念,我正在寻找它的解释几天但找不到任何解释。
4

1 回答 1

0

经过 2 天的时间寻找消息似乎混淆的问题后,我终于能够通过从我的工作人员中删除所有实例变量来解决这个问题。

这个线程给了我这样做的线索:https ://github.com/jondot/sneakers/issues/244

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

和:

我认为每个线程一个实例是要走的路。

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

于 2020-08-19T14:25:03.740 回答