0

私が見ているものを信じるのに苦労していますが、DJ がオブジェクトを適切にデシリアライズできていないようです。mongo で DJ レコードを確認すると、YAML でオブジェクトにtextフィールドが設定されていることがわかりますが、コードを実行するとtextフィールドが設定されません。最小限の再現コードを次に示します。

class Board
    include Mongoid::Document
    field :text, type: String

    def process_text_field
        if not self.text
            raise "Text field is blank"
        end
        # Text field gets processed
    end
end

# in a controller
def start_doing_something_slow
    board = Board.find(params[:id])
    board.text = "Text field is set"
    board.save!
    raise "Text disappeared!" unless board.text
    board.delay.process_text_field
    render json: {:result=>'ok'}
end

ブラウザでコントローラーメソッドを呼び出し、mongo で直接 DJ レコードを確認します。Boardオブジェクトのtextフィールドが正しく設定されていることを YAML で確認できます。しかし、DJ で実行すると、Text field is blank例外が発生します。

どういうわけか、オブジェクトを適切に逆シリアル化していません。

4

1 に答える 1

0

これを理解するのに約1週間かかったので、この罠に陥った他の人を助けるためにここに投稿します. これは、delayed_job_mongoidの既知のバグであることが判明しました。そして、10 か月間、バグ レポートに簡単な修正が記載されています。

データベースへのインプロセス キャッシング レイヤーとして機能する mongoid で ID マップを使用すると、問題が発生します。通常の Web リクエストでは、各リクエスト間でキャッシュがクリアされるため、コントローラー メソッドは古いバージョンのオブジェクトを使用しません。しかし、delayed_job_mongoid は、このパッチがないとジョブ間のキャッシュをクリアしません (これをまとめました): https://github.com/collectiveidea/delayed_job_mongoid/pull/38

その結果、遅延したジョブは、前に実行されたオブジェクトによっては古いバージョンのオブジェクトを使用している場合があり、何が起こっているのかを理解するまで追跡するのが非常に困難な、本当に奇妙で不可解なエラーが発生します。

于 2013-04-23T17:34:45.977 に答える