У меня есть обертка, которая регулярно отправляет пользовательские обновления на внешнюю службу, работающую внутри рабочего лица Sidekiq. У каждого пользователя есть свой собственный Sidekiq Job. Sidekiq настроен на использование 20 потоков. Это приложение Rails 5.0.1, MRI Ruby 2.3.0. Веб-сервер - сообщество пассажиров.Мутации Ruby Object в пределах sidekiq работников
Если я более упростить, код выглядит следующим образом:
class ProviderUserUpdateJob < ApplicationJob
queue_as :default
def perform(user_id)
user = User.find(user_id)
Provider::User.new(user).push_update
end
end
class Provider::User
def initialize(user)
@user = user
end
def push_update
SomeApiWrapper.call(
user_id: @user.id,
status: @user.status
)
end
....
end
Теперь большая проблема, что у меня есть только на производстве, и я, наконец, поймала вверх, глядя на журналы можно суммировать следующим образом:
class Provider::User
def initialize(user)
@user = user
end
def push_update
SomeApiWrapper.call(
user_id: @user.id, # Some user
status: @user.status # NOT THE SAME USER !!! (and I have no idea where he is coming from)
)
end
....
end
2 Вопросы:
Как это возможно? Это происходит от провайдера :: Пользователь по сути является глобально доступным объектом, поэтому из потоков в потоки все смешивается с мутирующим супом ?!
Если я использую только «функциональный» стиль, без каких-либо экземпляров, передавая параметры и выходы из статических методов в статические методы, может ли он решить мою проблему, или я совершенно не прав? Как я могу это исправить?
В конечном счете, есть ли способ действительно сразиться с этим кодом, чтобы я мог не смешивать данные пользователей?
_ «Если я более упрощаю, код выглядит так» _ - и ошибка все еще происходит с этим упрощенным кодом? – Stefan
Ха-ха, хорошо. Виноват. Но, хотя это упрощено, точное место и поведение проблемы остаются такими же, как и в исходном коде: «@user» указывает на что-то еще, от одной строки к другой, случайным образом, на производстве. Между двумя последовательными вызовами переменной «@user» нет абсолютно ничего, и это здесь не упрощается. – gbarillot
Могут ли вызовы 'id' или' status' иметь побочные эффекты, которые мутируют приемник? Если нет, существует ли поток SomeApiWrapper.call? – Stefan