I have a sneaker worker(given below) as a backend of a chatbot.
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
The problem I am facing here is that when I run sneaker with more than 1 thread and multiple users are chatting at the same time, then the ampq event which comes slightly later cause to override the @session_id
and as a result, the second user gets two questions and the first one gets none. This happens because by the time 1st event is getting process the second event came and override @session_id. Now when it's time to send the next question to the first user by using @session_id, the question get's send to the second user.
work
method and any instance variables
I create in it works like global mutable data for sneaker's threads?How does Puma manage these things? It is a multi-threaded app server and we use instance variables in controllers and it manages to serve multiple requests simultaneously. Does it mean that Puma handles this multi-contexting implicitly and Sneakers don't?
After 2 days of searching for an issue where messages seemed to get mixed up I was finally able to solve this by removing all instance variables from my workers.
This thread gave me the clue to do so: https://github.com/jondot/sneakers/issues/244
maybe we should simply disallow instance variables in workers since changing the behavior to instantiate multiple worker instances might break existing code somehow
and:
I think that an instance per thread is the way to go.
So when you remove your instance variables you should be fine!