2017-02-01 23 views
0

私はHerokuでresqueを使用しています。これは時々SIGTERMでジョブを中断します。複雑なジョブでresque-statusを指定してSIGTERMを処理する方法

は、これまでのところ、私はシンプルでこれを扱ってきました:

def process(options) 
    do_the_job 
rescue Resque::TermException 
    self.defer options 
end 

私たちは仕事を追跡できるように、我々はresqueステータスを使い始めましたが、明らかに上記の方法は、ジョブとしてなることを破ります実際にそれが別の仕事に延期されたときに完了したことを示します。

現在の考えでは、resqueで現在のジョブを延期する代わりに、SIGTERMによって失敗したジョブを再キューする別のジョブが必要です。

def process(options) 
    do_part1 unless options['part1_finished'] 
    options['part1_finished'] 
    do_part2 
rescue Resque::TermException 
    self.defer options 
end 

は単にdo_part1が繰り返されます際にこれらのジョブが例外を引き起こす救出し、単に再試行を取り除く:

トリックは、いくつかのジョブがより複雑であることに入っています。

答えて

0

resque-statusがどのように機能するかをより深く見ると、resque-statusが使用するのと同じパラメータを使用して、re-queueに対してresqueにまっすぐに進むことができます。

def process 
    do_part1 unless options['part1_finished'] 
    options['part1_finished'] 
    do_part2 
rescue Resque::TermException 
    Resque.enqueue self.class, uuid, options 
    raise DeferredToNewJob 
end 

もちろん、これは文書化されていないので、将来のリリースのresque-statusと互換性がない可能性があります。

ドローバックがあります。そのジョブが失敗してから新しいジョブが取得されるまでの間に、最初のジョブのステータスはresque-statusによってレポートされます。 これは新しい例外を再発生させる理由です。そうしないと、新しい従業員が古いジョブを取得するまでジョブのステータスが完了して表示されます。これは、待機中のプロセスとジョブの完了を待っているプロセスを混乱させる可能性があります。

新しい例外DeferredToNewJobを発生させると、ジョブのステータスが一時的に表示され、フロントエンドでの処理が簡単になり、特定の例外が自動的に再キュー障害キューからクリアされます。

UPDATE

resque-ステータスはon_failureハンドラのサポートを提供します。この名前のメソッドは、クラスのインスタンスメソッドとして定義されている場合、我々はこれをさらに簡単にすることができ

ここに私のon_failureはこれで

def on_failure(e) 
    if e.is_a? DeferredToNewJob 
    tick('Waiting for new job') 
    else 
    raise e 
    end 
end 

だ場所での仕事は、基本的には失敗した状態では時間を費やしていません状態を見ているプロセスのために。 さらに、resque-statusがこのハンドラを検出した場合、resqueまで例外を発生させないため、失敗したキューには追加されません。

関連する問題