2017-01-24 2 views
0

私は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つの質問:

  1. どのようにこのことも可能?それはProvider :: Userから来ていますか?スレッドからスレッドまで、すべてが突然変異するスープに混ざり合っていますか?

  2. 私はそれが私の問題を解決したり、私は完全に間違っていることができ、静的メソッドに静的メソッドからのパラメータおよび出力を渡し、任意のインスタンスなしに、「機能的」なスタイルを使用している場合は?これをどうすれば解決できますか?

最終的に、この種のコードを実際にテストする方法はありますか?私はユーザーデータを混ぜ合わせないようにしていますか?

+0

を_ _「私はオーバー簡素化した場合、コードは次のようになります」 - とバグはまだその単純化されたコードで発生しますか? – Stefan

+0

ハハ、ok。私の悪い。しかし、単純化されていますが、問題の正確な場所と動作は、元のコードと同じです。「@user」は、ある行から別の行に何かを無作為に指し示しています。 "@user"変数への2回の連続した呼び出しの間には何もありませんが、ここでは簡略化されていません。 – gbarillot

+0

'id'または' status'への呼び出しに、受信機を変更する副作用がありますか?もしそうでなければ、 'SomeApiWrapper.call'はスレッドセーフですか? – Stefan

答えて

0

これはダミーのデータです。私はちょうど複雑な説明でそれを把握しようと2時間失ったが、答えは、単純に、私のDBにあった。よくやった: -/

関連する問題