2

Rails 4.2 で通常の速度で実行される ActiveJob を作成しようとしています。ジョブは初めて呼び出されますが、再度開始されません。私のコードは、perform_later を呼び出そうとした後、以下の例外をスローしています。

ログ出力

[ActiveJob] Enqueued ProcessInboxJob (Job ID: 76a63689-e330-47a1-af92-8e4838b508ae) to Inline(default)
[ActiveJob] [ProcessInboxJob] [76a63689-e330-47a1-af92-8e4838b508ae] Performing ProcessInboxJob from Inline(default)
ProcessInboxJob running...
[ActiveJob] [ProcessInboxJob] [76a63689-e330-47a1-af92-8e4838b508ae] [AWS S3 200 0.358441 0 retries] list_objects(:bucket_name=>"...",:max_keys=>1000)  

[ActiveJob] [ProcessInboxJob] [76a63689-e330-47a1-af92-8e4838b508ae] Enqueued ProcessInboxJob (Job ID: dfd3dd7a-06ab-4dba-9bbf-ce1ad606f7e5) to Inline(default) with arguments: {:wait=>30 seconds}
[ActiveJob] [ProcessInboxJob] [76a63689-e330-47a1-af92-8e4838b508ae] Performed ProcessInboxJob from Inline(default) in 599.72ms
Exiting
/Users/antarrbyrd/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/activejob-4.2.0/lib/active_job/arguments.rb:60:in `serialize_argument': Unsupported argument type: ActiveSupport::Duration (ActiveJob::SerializationError)

process_inbox_job.rb

class ProcessInboxJob < ActiveJob::Base
  queue_as :default
  #FREQUENCY = 3.minutes
  def perform()
    # do some work
  end
  # reschedule job
  after_perform do |job|
    self.class.perform_later(wait: 30.seconds)
  end
end
4

3 に答える 3

2

@bcdが言ったようself.class.set(wait: 30.seconds).perform_laterに、キューイングをサポートするキューアダプター、つまりデフォルトの(インライン)アダプターではないキューアダプターを使用する必要があります。

将来の読者に役立つかもしれない再スケジュールの問題について別の視点を与えるために投稿します.

after_perform例外が発生した場合は呼び出されませが、ジョブを再スケジュールするのに悪い場所にはなりません。ジョブに例外がある場合は、(クラス メソッドを使用してrescue_from) レスキューし、バックエンドがまだ処理していない場合は自分自身に通知を送信することをお勧めします。

その後、(データ内またはコード内で) 問題の修正を試み、(可能であれば) 再試行するか、同様のジョブを再度キューに入れることができます。

スケジューリングに関しては、activejob-scheduler が優れており、resque だけでは機能しませんが、いくつかの欠点があります。

これはメモリ内遅延を実行する rufus-scheduler を使用するため、サーバーが再起動するたびにすべてのスケジューリング情報が失われ、一部のタスクでは実際に問題になる可能性があります (私は 1 か月後にタスクをスケジュールし、毎週アプリを更新します) 、つまり毎回再起動します)。

また、backburner を使用した Beanstalk など、実際のキューイング バックエンドを使用するすべての利点が失われます。

また、ActiveJob-scheduler は正確なタイミングでジョブを実行すると主張していますが、これは誤りです。ActiveJob アダプターは指定された時間に実行されますが、セットアップによっては、ジョブが実際に実行されるまでに時間がかかる場合があります (別のサーバーでジョブを実行する場合など)。

最後に、最初のスケジューリングでは、ワーカーの開始時にジョブが存在するかどうかを確認し、必要に応じてスケジュールするコードを含めることができます。

総括する、

はい、ActiveJob-Scheduler は優れていますが、ActiveJob 機能の一部が失われ、すべてを実行できるわけではありません。

于 2015-04-20T14:33:53.747 に答える
2

構文は、self.class.set(wait: 30.seconds).perform_later です。しかし、それは信頼できる方法ではありません。例外が発生した場合、チェーンが壊れます。また、最初のジョブをスケジュールする必要があります。resque を使用する場合は、https://rubygems.org/gems/activejob-schedulerを使用できます

于 2015-01-13T17:13:08.090 に答える