class QueueClassicPlus::CustomWorker
Constants
- BACKOFF_WIDTH
- CONNECTION_ERRORS
- FailedQueue
Public Instance Methods
handle_failure(job, e)
click to toggle source
# File lib/queue_classic_plus/worker.rb, line 10 def handle_failure(job, e) QueueClassicPlus.logger.info "Handling exception #{e.class} - #{e.message} for job #{job[:id]}" force_retry = false if connection_error?(e) # If we've got here, unfortunately ActiveRecord's rollback mechanism may # not have kicked in yet and we might be in a failed transaction. To be # *absolutely* sure the retry/failure gets enqueued, we do a rollback # just in case (and if we're not in a transaction it will be a no-op). QueueClassicPlus.logger.info "Reset connection for job #{job[:id]}" @conn_adapter.connection.reset @conn_adapter.execute 'ROLLBACK' # We definitely want to retry because the connection was lost mid-task. force_retry = true end @failed_job = job if force_retry && !(failed_job_class.respond_to?(:disable_retries) && failed_job_class.disable_retries) Metrics.increment("qc.force_retry", source: @q_name) retry_with_remaining(e) # The mailers doesn't have a retries_on? elsif failed_job_class && failed_job_class.respond_to?(:retries_on?) && failed_job_class.retries_on?(e) Metrics.increment("qc.retry", source: @q_name) retry_with_remaining(e) else enqueue_failed(e) end FailedQueue.delete(@failed_job[:id]) end
Private Instance Methods
backoff()
click to toggle source
# File lib/queue_classic_plus/worker.rb, line 69 def backoff (max_retries - (remaining_retries - 1)) * BACKOFF_WIDTH end
connection_error?(e)
click to toggle source
# File lib/queue_classic_plus/worker.rb, line 73 def connection_error?(e) CONNECTION_ERRORS.any? { |klass| e.kind_of? klass } || (e.respond_to?(:original_exception) && CONNECTION_ERRORS.any? { |klass| e.original_exception.kind_of? klass }) end
enqueue_failed(e)
click to toggle source
# File lib/queue_classic_plus/worker.rb, line 79 def enqueue_failed(e) sql = "INSERT INTO #{QC::TABLE_NAME} (q_name, method, args, last_error) VALUES ('failed_jobs', $1, $2, $3)" last_error = e.backtrace ? ([e.message] + e.backtrace ).join("\n") : e.message QC.default_conn_adapter.execute sql, @failed_job[:method], JSON.dump(@failed_job[:args]), last_error QueueClassicPlus.exception_handler.call(e, @failed_job) Metrics.increment("qc.errors", source: @q_name) end
failed_job_class()
click to toggle source
# File lib/queue_classic_plus/worker.rb, line 61 def failed_job_class begin Object.const_get(@failed_job[:method].split('.')[0]) rescue NameError nil end end
max_retries()
click to toggle source
# File lib/queue_classic_plus/worker.rb, line 53 def max_retries failed_job_class.respond_to?(:max_retries) ? failed_job_class.max_retries : 5 end
remaining_retries()
click to toggle source
# File lib/queue_classic_plus/worker.rb, line 57 def remaining_retries (@failed_job[:remaining_retries] || max_retries).to_i end
retry_with_remaining(e)
click to toggle source
# File lib/queue_classic_plus/worker.rb, line 45 def retry_with_remaining(e) if remaining_retries > 0 failed_job_class.restart_in(backoff, remaining_retries - 1, *@failed_job[:args]) else enqueue_failed(e) end end