【问题标题】:Rails 5 delayed job, how to check the job statusRails 5延迟作业,如何检查作业状态
【发布时间】:2020-04-05 11:59:06
【问题描述】:

我在带有“delayed_job_active_record”gem 的 Rails 5 项目中使用延迟作业。

我不知道如何检查作业的状态。

我设法让延迟的工作运行。由于处理上传文件的问题(这是另一个问题),作业失败。

在我的控制器中:

def create
  @upload = Upload.create(status: "in progress")
  @upload.delay.create_ln(lecture_note_params, current_user, @upload.id)
  render json: {"status": @upload.status, "id": @upload.id}, status: 200
end

这是我上传模型的模型代码:

class Upload < ApplicationRecord
    def create_ln(lecture_note_params, current_user, upload_id)
         @lecture_note = LectureNote.new(lecture_note_params.merge(user: current_user))
         @lecture_note.upload_id = upload_id
        if @lecture_note.save
          #nothing
        else
          logger.info @lecture_note.errors.full_messages.to_sentence
          @upload.update(error: @lecture_note.errors.full_messages.to_sentence, status: "error")      
        end
    end

end

讲义不保存。由于上述原因,它们失败了。我需要上传模型来更新错误状态。我该怎么做?

我可以在控制台中看到延迟的作业:

irb(main):002:0> ap Delayed::Job.last
D, [2019-12-12T06:12:08.014249 #4] DEBUG -- :   Delayed::Backend::ActiveRecord::Job Load (6.3ms)  SELECT  `delayed_jobs`.* FROM `delayed_jobs` ORDER BY `delayed_jobs`.`id` DESC LIMIT 1
#<Delayed::Backend::ActiveRecord::Job:0x0000561edb710f70> {
            :id => 16,
      :priority => 0,
      :attempts => 1,
       :handler => "### ALL KINDS OF STUFF - REDACTED ###",
        :run_at => Thu, 12 Dec 2019 06:10:32 UTC +00:00,
     :locked_at => nil,
     :failed_at => Thu, 12 Dec 2019 06:11:17 UTC +00:00,
     :locked_by => nil,
         :queue => nil,
    :created_at => Thu, 12 Dec 2019 06:10:32 UTC +00:00,
    :updated_at => Thu, 12 Dec 2019 06:11:17 UTC +00:00
}

作业失败后,更新“failed_at”字段。如何访问它并更新我的上传模型?

这是上传文件时的日志文件:

D, [2019-12-12T06:11:17.846638 #4] DEBUG -- :   Upload Load (1.1ms)  SELECT  `uploads`.* FROM `uploads` WHERE `uploads`.`id` = 31 LIMIT 1
D, [2019-12-12T06:11:17.852741 #4] DEBUG -- :   User Load (1.4ms)  SELECT  `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
[Worker(host:575e618d-28f3-49a1-8545-88afa11b60d1 pid:4)] Job Upload#create_ln (id=16) RUNNING
I, [2019-12-12T06:11:17.853180 #4]  INFO -- : 2019-12-12T06:11:17+0000: [Worker(host:575e618d-28f3-49a1-8545-88afa11b60d1 pid:4)] Job Upload#create_ln (id=16) RUNNING
D, [2019-12-12T06:11:17.855002 #4] DEBUG -- :    (1.2ms)  BEGIN
I, [2019-12-12T06:11:17.855200 #4]  INFO -- : pdf to html running..............
I, [2019-12-12T06:11:17.855268 #4]  INFO -- : step 0 ..............
I, [2019-12-12T06:11:17.855326 #4]  INFO -- : step 1 ..............
I, [2019-12-12T06:11:17.855388 #4]  INFO -- : step 2 ..............
D, [2019-12-12T06:11:17.856673 #4] DEBUG -- :    (1.1ms)  ROLLBACK
[Worker(host:575e618d-28f3-49a1-8545-88afa11b60d1 pid:4)] Job Upload#create_ln (id=16) FAILED (0 prior attempts) with IOError: uninitialized stream
E, [2019-12-12T06:11:17.857261 #4] ERROR -- : 2019-12-12T06:11:17+0000: [Worker(host:575e618d-28f3-49a1-8545-88afa11b60d1 pid:4)] Job Upload#create_ln (id=16) FAILED (0 prior attempts) with IOError: uninitialized stream
[Worker(host:575e618d-28f3-49a1-8545-88afa11b60d1 pid:4)] Job Upload#create_ln (id=16) FAILED permanently because of 1 consecutive failures
E, [2019-12-12T06:11:17.857416 #4] ERROR -- : 2019-12-12T06:11:17+0000: [Worker(host:575e618d-28f3-49a1-8545-88afa11b60d1 pid:4)] Job Upload#create_ln (id=16) FAILED permanently because of 1 consecutive failures
D, [2019-12-12T06:11:17.858576 #4] DEBUG -- :    (0.9ms)  BEGIN
D, [2019-12-12T06:11:17.861961 #4] DEBUG -- :   SQL (1.6ms)  UPDATE `delayed_jobs` SET `last_error` = 'uninitialized stream\n/app/vendor/ruby-2.6.3/lib/ruby/2.6.0/tempfile.rb:221:in `path\'\n/app/vendor/ruby-2.6.3/lib/ruby/2.6.0/tempfile.rb:221:in `path\'\n/app/app/models/lecture_note.rb:60:in `pdf_to_html\'\n/app/vendor/bundle/ruby/2.6.0/gems/activesupport-5.0.7.1/lib/active_support/callbacks.rb:382:in `block in make_lambda\'\n/app/vendor/bundle/ruby/2.6.0/gems/activesupport-5.0.7.1/lib/active_support/callbacks.rb:150:in `block (2 levels) in halting_and_conditional\'\n/app/vendor/bundle/ruby/2.6.0/gems/activesupport-5.0.7.1/lib/active_support/callbacks.rb:770:in `block (2 levels) in deprecated_false_terminator\'\n/app/vendor/bundle/ruby/2.6.0/gems/activesupport-5.0.7.1/lib/active_support/callbacks.rb:769:in `catch\'\n/app/vendor/bundle/ruby/2.6.0/gems/activesupport-5.0.7.1/lib/active_support/callbacks.rb:769:in `block in deprecated_false_terminator\'\n/app/vendor/bundle/ruby/2.6.0/gems/activesupport-5.0.7.1/lib/active_support/callbacks.rb:151:in `block in halting_and_conditional\'\n/app/vendor/bundle/ruby/2.6.0/gems/activesupport-5.0.7.1/lib/active_support/callbacks.rb:454:in `block in call\'\n/app/vendor/bundle/ruby/2.6.0/gems/activesupport-5.0.7.1/lib/active_support/callbacks.rb:454:in `each\'\n/app/vendor/bundle/ruby/2.6.0/gems/activesupport-5.0.7.1/lib/active_support/callbacks.rb:454:in `call\'\n/app/vendor/bundle/ruby/2.6.0/gems/activesupport-5.0.7.1/lib/active_support/callbacks.rb:101:in `__run_callbacks__\'\n/app/vendor/bundle/ruby/2.6.0/gems/activesupport-5.0.7.1/lib/active_support/callbacks.rb:750:in `_run_validation_callbacks\'\n/app/vendor/bundle/ruby/2.6.0/gems/activemodel-5.0.7.1/lib/active_model/validations/callbacks.rb:113:in `run_validations!\'\n/app/vendor/bundle/ruby/2.6.0/gems/activemodel-5.0.7.1/lib/active_model/validations.rb:338:in `valid?\'\n/app/vendor/bundle/ruby/2.6.0/gems/activerecord-5.0.7.1/lib/active_record/validations.rb:65:in `valid?\'\n/app/vendor/bundle/ruby/2.6.0/gems/activerecord-5.0.7.1/lib/active_record/validations.rb:82:in `perform_validations\'\n/app/vendor/bundle/ruby/2.6.0/gems/activerecord-5.0.7.1/lib/active_record/validations.rb:44:in `save\'\n/app/vendor/bundle/ruby/2.6.0/gems/activerecord-5.0.7.1/lib/active_record/attribute_methods/dirty.rb:22:in `save\'\n/app/vendor/bundle/ruby/2.6.0/gems/activerecord-5.0.7.1/lib/active_record/transactions.rb:319:in `block (2 levels) in save\'\n/app/vendor/bundle/ruby/2.6.0/gems/activerecord-5.0.7.1/lib/active_record/transactions.rb:395:in `block in with_transaction_returning_status\'\n/app/vendor/bundle/ruby/2.6.0/gems/activerecord-5.0.7.1/lib/active_record/connection_adapters/abstract/database_statements.rb:232:in `block in transaction\'\n/app/vendor/bundle/ruby/2.6.0/gems/activerecord-5.0.7.1/lib/active_record/connection_adapters/abstract/transaction.rb:189:in `within_new_transaction\'\n/app/vendor/bundle/ruby/2.6.0/gems/activerecord-5.0.7.1/lib/active_record/connection_adapters/abstract/database_statements.rb:232:in `transaction\'\n/app/vendor/bundle/ruby/2.6.0/gems/activerecord-5.0.7.1/lib/active_record/transactions.rb:211:in `transaction\'\n/app/vendor/bundle/ruby/2.6.0/gems/activerecord-5.0.7.1/lib/active_record/transactions.rb:392:in `with_transaction_returning_status\'\n/app/vendor/bundle/ruby/2.6.0/gems/activerecord-5.0.7.1/lib/active_record/transactions.rb:319:in `block in save\'\n/app/vendor/bundle/ruby/2.6.0/gems/activerecord-5.0.7.1/lib/active_record/transactions.rb:334:in `rollback_active_record_state!\'\n/app/vendor/bundle/ruby/2.6.0/gems/activerecord-5.0.7.1/lib/active_record/transactions.rb:318:in `save\'\n/app/vendor/bundle/ruby/2.6.0/gems/activerecord-5.0.7.1/lib/active_record/suppressor.rb:41:in `save\'\n/app/app/models/upload.rb:7:in `create_ln\'\n/app/vendor/bundle/ruby/2.6.0/gems/delayed_job-4.1.8/lib/delayed/performable_method.rb:26:in `perform\'\n/app/vendor/bundle/ruby/2.6.0/gems/delayed_job-4.1.8/lib/delayed/backend/base.rb:81:in `block in invoke_job\'\n/app/vendor/bundle/ruby/2.6.0/gems/delayed_job-4.1.8/lib/delayed/lifecycle.rb:61:in `block in initialize\'\n/app/vendor/bundle/ruby/2.6.0/gems/delayed_job-4.1.8/lib/delayed/lifecycle.rb:66:in `execute\'\n/app/vendor/bundle/ruby/2.6.0/gems/delayed_job-4.1.8/lib/delayed/lifecycle.rb:40:in `run_callbacks\'\n/app/vendor/bundle/ruby/2.6.0/gems/delayed_job-4.1.8/lib/delayed/backend/base.rb:78:in `invoke_job\'\n/app/vendor/bundle/ruby/2.6.0/gems/delayed_job-4.1.8/lib/delayed/worker.rb:230:in `block (2 levels) in run\'\n/app/vendor/ruby-2.6.3/lib/ruby/2.6.0/timeout.rb:93:in `block in timeout\'\n/app/vendor/ruby-2.6.3/lib/ruby/2.6.0/timeout.rb:103:in `timeout\'\n/app/vendor/bundle/ruby/2.6.0/gems/delayed_job-4.1.8/lib/delayed/worker.rb:230:in `block in run\'\n/app/vendor/ruby-2.6.3/lib/ruby/2.6.0/benchmark.rb:308:in `realtime\'\n/app/vendor/bundle/ruby/2.6.0/gems/delayed_job-4.1.8/lib/delayed/worker.rb:229:in `run\'\n/app/vendor/bundle/ruby/2.6.0/gems/delayed_job-4.1.8/lib/delayed/worker.rb:312:in `block in reserve_and_run_one_job\'\n/app/vendor/bundle/ruby/2.6.0/gems/delayed_job-4.1.8/lib/delayed/lifecycle.rb:61:in `block in initialize\'\n/app/vendor/bundle/ruby/2.6.0/gems/delayed_job-4.1.8/lib/delayed/lifecycle.rb:66:in `execute\'\n/app/vendor/bundle/ruby/2.6.0/gems/delayed_job-4.1.8/lib/delayed/lifecycle.rb:40:in `run_callbacks\'\n/app/vendor/bundle/ruby/2.6.0/gems/delayed_job-4.1.8/lib/delayed/worker.rb:312:in `reserve_and_run_one_job\'\n/app/vendor/bundle/ruby/2.6.0/gems/delayed_job-4.1.8/lib/delayed/worker.rb:213:in `block in work_off\'\n/app/vendor/bundle/ruby/2.6.0/gems/delayed_job-4.1.8/lib/delayed/worker.rb:212:in `times\'\n/app/vendor/bundle/ruby/2.6.0/gems/delayed_job-4.1.8/lib/delayed/worker.rb:212:in `work_off\'\n/app/vendor/bundle/ruby/2.6.0/gems/delayed_job-4.1.8/lib/delayed/worker.rb:175:in `block (4 levels) in start\'\n/app/vendor/ruby-2.6.3/lib/ruby/2.6.0/benchmark.rb:308:in `realtime\'\n/app/vendor/bundle/ruby/2.6.0/gems/delayed_job-4.1.8/lib/delayed/worker.rb:174:in `block (3 levels) in start\'\n/app/vendor/bundle/ruby/2.6.0/gems/delayed_job-4.1.8/lib/delayed/lifecycle.rb:61:in `block in initialize\'\n/app/vendor/bundle/ruby/2.6.0/gems/delayed_job-4.1.8/lib/delayed/lifecycle.rb:66:in `execute\'\n/app/vendor/bundle/ruby/2.6.0/gems/delayed_job-4.1.8/lib/delayed/lifecycle.rb:40:in `run_callbacks\'\n/app/vendor/bundle/ruby/2.6.0/gems/delayed_job-4.1.8/lib/delayed/worker.rb:173:in `block (2 levels) in start\'\n/app/vendor/bundle/ruby/2.6.0/gems/delayed_job-4.1.8/lib/delayed/worker.rb:172:in `loop\'\n/app/vendor/bundle/ruby/2.6.0/gems/delayed_job-4.1.8/lib/delayed/worker.rb:172:in `block in start\'\n/app/vendor/bundle/ruby/2.6.0/gems/delayed_job-4.1.8/lib/delayed/plugins/clear_locks.rb:7:in `block (2 levels) in <class:ClearLocks>\'\n/app/vendor/bundle/ruby/2.6.0/gems/delayed_job-4.1.8/lib/delayed/lifecycle.rb:79:in `block (2 levels) in add\'\n/app/vendor/bundle/ruby/2.6.0/gems/delayed_job-4.1.8/lib/delayed/lifecycle.rb:61:in `block in initialize\'\n/app/vendor/bundle/ruby/2.6.0/gems/delayed_job-4.1.8/lib/delayed/lifecycle.rb:79:in `block in add\'\n/app/vendor/bundle/ruby/2.6.0/gems/delayed_job-4.1.8/lib/delayed/lifecycle.rb:66:in `execute\'\n/app/vendor/bundle/ruby/2.6.0/gems/delayed_job-4.1.8/lib/delayed/lifecycle.rb:40:in `run_callbacks\'\n/app/vendor/bundle/ruby/2.6.0/gems/delayed_job-4.1.8/lib/delayed/worker.rb:171:in `start\'\n/app/vendor/bundle/ruby/2.6.0/gems/delayed_job-4.1.8/lib/delayed/tasks.rb:9:in `block (2 levels) in <top (required)>\'\n/app/vendor/bundle/ruby/2.6.0/gems/rake-12.3.3/lib/rake/task.rb:273:in `block in execute\'\n/app/vendor/bundle/ruby/2.6.0/gems/rake-12.3.3/lib/rake/task.rb:273:in `each\'\n/app/vendor/bundle/ruby/2.6.0/gems/rake-12.3.3/lib/rake/task.rb:273:in `execute\'\n/app/vendor/bundle/ruby/2.6.0/gems/rake-12.3.3/lib/rake/task.rb:214:in `block in invoke_with_call_chain\'\n/app/vendor/ruby-2.6.3/lib/ruby/2.6.0/monitor.rb:230:in `mon_synchronize\'\n/app/vendor/bundle/ruby/2.6.0/gems/rake-12.3.3/lib/rake/task.rb:194:in `invoke_with_call_chain\'\n/app/vendor/bundle/ruby/2.6.0/gems/rake-12.3.3/lib/rake/task.rb:183:in `invoke\'\n/app/vendor/bundle/ruby/2.6.0/gems/rake-12.3.3/lib/rake/application.rb:160:in `invoke_task\'\n/app/vendor/bundle/ruby/2.6.0/gems/rake-12.3.3/lib/rake/application.rb:116:in `block (2 levels) in top_level\'\n/app/vendor/bundle/ruby/2.6.0/gems/rake-12.3.3/lib/rake/application.rb:116:in `each\'\n/app/vendor/bundle/ruby/2.6.0/gems/rake-12.3.3/lib/rake/application.rb:116:in `block in top_level\'\n/app/vendor/bundle/ruby/2.6.0/gems/rake-12.3.3/lib/rake/application.rb:125:in `run_with_threads\'\n/app/vendor/bundle/ruby/2.6.0/gems/rake-12.3.3/lib/rake/application.rb:110:in `top_level\'\n/app/vendor/bundle/ruby/2.6.0/gems/rake-12.3.3/lib/rake/application.rb:83:in `block in run\'\n/app/vendor/bundle/ruby/2.6.0/gems/rake-12.3.3/lib/rake/application.rb:186:in `standard_exception_handling\'\n/app/vendor/bundle/ruby/2.6.0/gems/rake-12.3.3/lib/rake/application.rb:80:in `run\'\n/app/vendor/bundle/ruby/2.6.0/gems/rake-12.3.3/exe/rake:27:in `<top (required)>\'\n/app/vendor/bundle/ruby/2.6.0/bin/rake:23:in `load\'\n/app/vendor/bundle/ruby/2.6.0/bin/rake:23:in `<top (required)>\'\n/app/vendor/bundle/ruby/2.6.0/gems/bundler-1.17.3/lib/bundler/cli/exec.rb:74:in `load\'\n/app/vendor/bundle/ruby/2.6.0/gems/bundler-1.17.3/lib/bundler/cli/exec.rb:74:in `kernel_load\'\n/app/vendor/bundle/ruby/2.6.0/gems/bundler-1.17.3/lib/bundler/cli/exec.rb:28:in `run\'\n/app/vendor/bundle/ruby/2.6.0/gems/bundler-1.17.3/lib/bundler/cli.rb:463:in `exec\'\n/app/vendor/bundle/ruby/2.6.0/gems/bundler-1.17.3/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run\'\n/app/vendor/bundle/ruby/2.6.0/gems/bundler-1.17.3/lib/bundler/vendor/thor/lib/thor/invocation.rb:126:in `invoke_command\'\n/app/vendor/bundle/ruby/2.6.0/gems/bundler-1.17.3/lib/bundler/vendor/thor/lib/thor.rb:387:in `dispatch\'\n/app/vendor/bundle/ruby/2.6.0/gems/bundler-1.17.3/lib/bundler/cli.rb:27:in `dispatch\'\n/app/vendor/bundle/ruby/2.6.0/gems/bundler-1.17.3/lib/bundler/vendor/thor/lib/thor/base.rb:466:in `start\'\n/app/vendor/bundle/ruby/2.6.0/gems/bundler-1.17.3/lib/bundler/cli.rb:18:in `start\'\n/app/vendor/bundle/ruby/2.6.0/gems/bundler-1.17.3/exe/bundle:30:in `block in <top (required)>\'\n/app/vendor/bundle/ruby/2.6.0/gems/bundler-1.17.3/lib/bundler/friendly_errors.rb:124:in `with_friendly_errors\'\n/app/vendor/bundle/ruby/2.6.0/gems/bundler-1.17.3/exe/bundle:22:in `<top (required)>\'\n/app/bin/bundle:3:in `load\'\n/app/bin/bundle:3:in `<main>\'', `attempts` = 1, `failed_at` = '2019-12-12 06:11:17', `updated_at` = '2019-12-12 06:11:17' WHERE `delayed_jobs`.`id` = 16
D, [2019-12-12T06:11:17.867680 #4] DEBUG -- :    (5.1ms)  COMMIT
D, [2019-12-12T06:11:17.870699 #4] DEBUG -- :   SQL (1.8ms)  UPDATE `delayed_jobs` SET `delayed_jobs`.`locked_at` = '2019-12-12 06:11:17', `delayed_jobs`.`locked_by` = 'host:575e618d-28f3-49a1-8545-88afa11b60d1 pid:4' WHERE ((run_at <= '2019-12-12 06:11:17.867786' AND (locked_at IS NULL OR locked_at < '2019-12-12 02:11:17.867819') OR locked_by = 'host:575e618d-28f3-49a1-8545-88afa11b60d1 pid:4') AND failed_at IS NULL) ORDER BY priority ASC, run_at ASC LIMIT 1
[Worker(host:575e618d-28f3-49a1-8545-88afa11b60d1 pid:4)] 8 jobs processed at 13.8130 j/s, 8 failed
I, [2019-12-12T06:11:17.870885 #4]  INFO -- : 2019-12-12T06:11:17+0000: [Worker(host:575e618d-28f3-49a1-8545-88afa11b60d1 pid:4)] 8 jobs processed at 13.8130 j/s, 8 failed
D, [2019-12-12T06:11:17.873258 #4] DEBUG -- :   SQL (1.2ms)  UPDATE `delayed_jobs` SET `delayed_jobs`.`locked_at` = '2019-12-12 06:11:17', `delayed_jobs`.`locked_by` = 'host:575e618d-28f3-49a1-8545-88afa11b60d1 pid:4' WHERE ((run_at <= '2019-12-12 06:11:17.870973' AND (locked_at IS NULL OR locked_at < '2019-12-12 02:11:17.871010') OR locked_by = 'host:575e618d-28f3-49a1-8545-88afa11b60d1 pid:4') AND failed_at IS NULL) ORDER BY priority ASC, run_at ASC LIMIT 1
D, [2019-12-12T06:11:22.878755 #4] DEBUG -- :   SQL (1.5ms)  UPDATE `delayed_jobs` SET `delayed_jobs`.`locked_at` = '2019-12-12 06:11:22', `delayed_jobs`.`locked_by` = 'host:575e618d-28f3-49a1-8545-88afa11b60d1 pid:4' WHERE ((run_at <= '2019-12-12 06:11:22.876103' AND (locked_at IS NULL OR locked_at < '2019-12-12 02:11:22.876164') OR locked_by = 'host:575e618d-28f3-49a1-8545-88afa11b60d1 pid:4') AND failed_at IS NULL) ORDER BY priority ASC, run_at ASC LIMIT 1
D, [2019-12-12T06:11:27.882776 #4] DEBUG -- :   SQL (1.6ms)  UPDATE `delayed_jobs` SET `delayed_jobs`.`locked_at` = '2019-12-12 06:11:27', `delayed_jobs`.`locked_by` = 'host:575e618d-28f3-49a1-8545-88afa11b60d1 pid:4' WHERE ((run_at <= '2019-12-12 06:11:27.880101' AND (locked_at IS NULL OR locked_at < '2019-12-12 02:11:27.880160') OR locked_by = 'host:575e618d-28f3-49a1-8545-88afa11b60d1 pid:4') AND failed_at IS NULL) ORDER BY priority ASC, run_at ASC LIMIT 1
D, [2019-12-12T06:11:32.890712 #4] DEBUG -- :   SQL (1.6ms)  UPDATE `delayed_jobs` SET `delayed_jobs`.`locked_at` = '2019-12-12 06:11:32', `delayed_jobs`.`locked_by` = 'host:575e618d-28f3-49a1-8545-88afa11b60d1 pid:4' WHERE ((run_at <= '2019-12-12 06:11:32.887163' AND (locked_at IS NULL OR locked_at < '2019-12-12 02:11:32.887243') OR locked_by = 'host:575e618d-28f3-49a1-8545-88afa11b60d1 pid:4') AND failed_at IS NULL) ORDER BY priority ASC, run_at ASC LIMIT 1
D, [2019-12-12T06:11:37.894751 #4] DEBUG -- :   SQL (1.5ms)  UPDATE `delayed_jobs` SET `delayed_jobs`.`locked_at` = '2019-12-12 06:11:37', `delayed_jobs`.`locked_by` = 'host:575e618d-28f3-49a1-8545-88afa11b60d1 pid:4' WHERE ((run_at <= '2019-12-12 06:11:37.892094' AND (locked_at IS NULL OR locked_at < '2019-12-12 02:11:37.892153') OR locked_by = 'host:575e618d-28f3-49a1-8545-88afa11b60d1 pid:4') AND failed_at IS NULL) ORDER BY priority ASC, run_at ASC LIMIT 1
^C[Worker(host:575e618d-28f3-49a1-8545-88afa11b60d1 pid:4)] Exiting...
I, [2019-12-12T06:11:39.976787 #4]  INFO -- : 2019-12-12T06:11:39+0000: [Worker(host:575e618d-28f3-49a1-8545-88afa11b60d1 pid:4)] Exiting...
D, [2019-12-12T06:11:42.902214 #4] DEBUG -- :   SQL (5.4ms)  UPDATE `delayed_jobs` SET `delayed_jobs`.`locked_by` = NULL, `delayed_jobs`.`locked_at` = NULL WHERE `delayed_jobs`.`locked_by` = 'host:575e618d-28f3-49a1-8545-88afa11b60d1 pid:4'

【问题讨论】:

  • 你的create方法是通过js调用的吗?
  • Rails 被用作 API。控制器由JS触发,但方法在模型中运行。

标签: ruby-on-rails activerecord delayed-job


【解决方案1】:

一般来说,我们不应该检查作业。工作应该报告回来。 (观察者模式——我认为)

我通常会做以下一项或多项操作

  • ActionCable 通知工作进度(您的情况例外)
  • 在作业中捕获异常并更新上传状态
  • 使用第三方 gem(例如 activity_notification 进行通知。

DelayedJob proposed Global Hooks 但我认为它还没有实现。

【讨论】:

  • 谢谢 Tun,“在工作中捕获异常并更新上传状态”是有道理的。我将在哪里添加该代码?在发送到delayed_job 的方法中?就我而言,那将是 create_ln 。代码会是什么样子?
【解决方案2】:

好的,我找到了解决方案。 Tun 的回答为我指明了大方向(非常大的方向),但引导我走向了它。

delayed_job 有回调,但我不知道把它们放在哪里,或者如何使用它们。他们只是进入工作方法发生的模型。这在可用的文档中并不明显(无论如何对我来说)。

我看错了。我已经有上传类来管理讲义的创建。因此,使用回调我可以让作业更新具有状态的类。这就是我们最终需要的。

def failure(job) 方法成功了!

我不是 100% 了解这些回调实际上是如何在幕后工作的,但它们确实有效。

class Upload < ApplicationRecord


    def create_ln(lecture_note_params, current_user, upload_id)
         @lecture_note = LectureNote.new(lecture_note_params.merge(user: current_user))
         @lecture_note.upload_id = upload_id
        # if @lecture_note.save
        #   #nothing
        # else
        #   logger.info @lecture_note.errors.full_messages.to_sentence
        #   @upload.update(error: @lecture_note.errors.full_messages.to_sentence, status: "error")      
        # end
        begin
          @lecture_note.save
        rescue Exception => e
          puts @lecture_note.errors.full_messages.to_sentence
          self.update(error: @lecture_note.errors.full_messages.to_sentence, status: "error")      
        end
    end

     def success(job)
      puts "Job complete ------->"
    end

    def error(job, exception)
      puts "Job failed ERROR ------->"
      puts @lecture_note.errors.full_messages.to_sentence
      self.update(error: @lecture_note.errors.full_messages.to_sentence, status: "error") 
    end

    # def after(job)
    #   # Do something useful here
    # end

    def failure(job)
     puts "Job failed FAILURE ------->"
      puts @lecture_note.errors.full_messages.to_sentence
      self.update(error: @lecture_note.errors.full_messages.to_sentence, status: "error") 
    end
end

【讨论】:

猜你喜欢
  • 2013-11-26
  • 2020-09-03
  • 2023-04-03
  • 1970-01-01
  • 2013-05-01
  • 2012-04-20
  • 2016-03-29
  • 2016-10-10
  • 1970-01-01
相关资源
最近更新 更多