From 718899da189b82db7c362427f060904e314c4ba4 Mon Sep 17 00:00:00 2001 From: Martin Gruner Date: Wed, 14 Jul 2021 18:55:57 +0000 Subject: [PATCH] Fixes #3653 - Freshdesk import fails with timeout error. --- app/jobs/application_job.rb | 5 ++++ app/jobs/async_import_job.rb | 6 +++++ .../delayed_jobs_timeout_per_job.rb | 25 +++++++++++++++++++ .../unit/import/freshdesk/requester.rb | 4 +-- 4 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 config/initializers/delayed_jobs_timeout_per_job.rb diff --git a/app/jobs/application_job.rb b/app/jobs/application_job.rb index 625c902b0..1c9949e68 100644 --- a/app/jobs/application_job.rb +++ b/app/jobs/application_job.rb @@ -7,6 +7,11 @@ class ApplicationJob < ActiveJob::Base ActiveJob::Logging::LogSubscriber.detach_from :active_job + # See config/initializers/delayed_jobs_timeout_per_job.rb for details. + def self.max_run_time + 4.hours + end + # Automatically retry jobs that encountered a deadlock # retry_on ActiveRecord::Deadlocked diff --git a/app/jobs/async_import_job.rb b/app/jobs/async_import_job.rb index 6c04ca1b4..f280de630 100644 --- a/app/jobs/async_import_job.rb +++ b/app/jobs/async_import_job.rb @@ -1,6 +1,12 @@ # Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/ class AsyncImportJob < ApplicationJob + + # See config/initializers/delayed_jobs_timeout_per_job.rb for details. + def self.max_run_time + 7.days + end + def perform(import_job) import_job.start end diff --git a/config/initializers/delayed_jobs_timeout_per_job.rb b/config/initializers/delayed_jobs_timeout_per_job.rb new file mode 100644 index 000000000..b83f53faf --- /dev/null +++ b/config/initializers/delayed_jobs_timeout_per_job.rb @@ -0,0 +1,25 @@ +# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/ + +# Workaround for ActiveJob not supporting per-job timeouts with delayed_job. +# +# delayed_job does support this (https://github.com/collectiveidea/delayed_job#custom-jobs), +# but since ActiveJob's adapter places a JobWrapper class around the jobs, it fails to work. +# +# Solve this by delegating that method to the actual job class instead. + +# Set the maximum possible max_run_time for any job to a high value, and set a sensible default +# in ApplicationJob.max_run_time. Then specific jobs like AsyncImportJob can override this with a +# higher value. +Delayed::Worker.max_run_time = 7.days + +module ActiveJob + module QueueAdapters + class DelayedJobAdapter + class JobWrapper + def max_run_time + job_data['job_class'].constantize.max_run_time + end + end + end + end +end diff --git a/lib/sequencer/unit/import/freshdesk/requester.rb b/lib/sequencer/unit/import/freshdesk/requester.rb index 3c251de78..9a44e871f 100644 --- a/lib/sequencer/unit/import/freshdesk/requester.rb +++ b/lib/sequencer/unit/import/freshdesk/requester.rb @@ -15,7 +15,7 @@ class Sequencer return response if response.is_a? Net::HTTPOK handle_error response, iteration - rescue => e + rescue Net::HTTPClientError => e handle_exception e, iteration end end @@ -34,7 +34,7 @@ class Sequencer def handle_exception(e, iteration) logger.error e - logger.info "Sleeping 10 seconds after #{e.name} and retry (##{iteration + 1}/10)." + logger.info "Sleeping 10 seconds after #{e.class.name} and retry (##{iteration + 1}/10)." sleep 10 end