私はSidekiq労働者の内部で実行されている、定期的に、外部サービスへのユーザーの更新を送信するラッパーを持っています。各ユーザーには独自のSidekiqジョブがあります。 Sidekiqは20スレッドを使用するように設定されています。それはRails 5.0.1アプリ、MRI Ruby 2.3.0です。 WebserverはPassenger 5 Communityです。Rubyのオブジェクトの変異
私はオーバー簡素化した場合には、コードは次のようになります。今
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
、私は唯一の生産に持っていると私は最終的に次のように要約することができ、ログを見て、アップcatched BIG問題:
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つの質問:
どのようにこのことも可能?それはProvider :: Userから来ていますか?スレッドからスレッドまで、すべてが突然変異するスープに混ざり合っていますか?
私はそれが私の問題を解決したり、私は完全に間違っていることができ、静的メソッドに静的メソッドからのパラメータおよび出力を渡し、任意のインスタンスなしに、「機能的」なスタイルを使用している場合は?これをどうすれば解決できますか?
最終的に、この種のコードを実際にテストする方法はありますか?私はユーザーデータを混ぜ合わせないようにしていますか?
を_ _「私はオーバー簡素化した場合、コードは次のようになります」 - とバグはまだその単純化されたコードで発生しますか? – Stefan
ハハ、ok。私の悪い。しかし、単純化されていますが、問題の正確な場所と動作は、元のコードと同じです。「@user」は、ある行から別の行に何かを無作為に指し示しています。 "@user"変数への2回の連続した呼び出しの間には何もありませんが、ここでは簡略化されていません。 – gbarillot
'id'または' status'への呼び出しに、受信機を変更する副作用がありますか?もしそうでなければ、 'SomeApiWrapper.call'はスレッドセーフですか? – Stefan