debian-mirror-gitlab/app/workers/stuck_import_jobs_worker.rb

76 lines
2.7 KiB
Ruby
Raw Normal View History

2018-11-08 19:23:39 +05:30
# frozen_string_literal: true
2020-04-08 14:13:33 +05:30
class StuckImportJobsWorker # rubocop:disable Scalability/IdempotentWorker
2018-03-17 18:26:18 +05:30
include ApplicationWorker
2020-03-13 15:44:24 +05:30
# rubocop:disable Scalability/CronWorkerContext
# This worker updates several import states inline and does not schedule
# other jobs. So no context needed
2017-08-17 22:00:37 +05:30
include CronjobQueue
2020-03-13 15:44:24 +05:30
# rubocop:enable Scalability/CronWorkerContext
2017-08-17 22:00:37 +05:30
2019-12-21 20:55:43 +05:30
feature_category :importers
2019-12-26 22:10:19 +05:30
worker_resource_boundary :cpu
2019-12-21 20:55:43 +05:30
2018-03-17 18:26:18 +05:30
IMPORT_JOBS_EXPIRATION = 15.hours.to_i
2017-08-17 22:00:37 +05:30
def perform
2018-12-13 13:39:08 +05:30
import_state_without_jid_count = mark_import_states_without_jid_as_failed!
import_state_with_jid_count = mark_import_states_with_jid_as_failed!
2018-03-17 18:26:18 +05:30
Gitlab::Metrics.add_event(:stuck_import_jobs,
2018-12-13 13:39:08 +05:30
projects_without_jid_count: import_state_without_jid_count,
projects_with_jid_count: import_state_with_jid_count)
2018-03-17 18:26:18 +05:30
end
private
2018-12-13 13:39:08 +05:30
def mark_import_states_without_jid_as_failed!
enqueued_import_states_without_jid.each do |import_state|
import_state.mark_as_failed(error_message)
2018-03-17 18:26:18 +05:30
end.count
end
2018-12-05 23:21:45 +05:30
# rubocop: disable CodeReuse/ActiveRecord
2018-12-13 13:39:08 +05:30
def mark_import_states_with_jid_as_failed!
jids_and_ids = enqueued_import_states_with_jid.pluck(:jid, :id).to_h
2018-03-17 18:26:18 +05:30
2018-03-27 19:54:05 +05:30
# Find the jobs that aren't currently running or that exceeded the threshold.
completed_jids = Gitlab::SidekiqStatus.completed_jids(jids_and_ids.keys)
return unless completed_jids.any?
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
completed_import_state_ids = jids_and_ids.values_at(*completed_jids)
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
# We select the import states again, because they may have transitioned from
2018-03-27 19:54:05 +05:30
# scheduled/started to finished/failed while we were looking up their Sidekiq status.
2018-12-13 13:39:08 +05:30
completed_import_states = enqueued_import_states_with_jid.where(id: completed_import_state_ids)
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
completed_import_state_jids = completed_import_states.map { |import_state| import_state.jid }.join(', ')
2019-09-30 21:07:59 +05:30
Rails.logger.info("Marked stuck import jobs as failed. JIDs: #{completed_import_state_jids}") # rubocop:disable Gitlab/RailsLogger
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
completed_import_states.each do |import_state|
import_state.mark_as_failed(error_message)
2018-03-27 19:54:05 +05:30
end.count
2018-03-17 18:26:18 +05:30
end
2018-12-05 23:21:45 +05:30
# rubocop: enable CodeReuse/ActiveRecord
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
def enqueued_import_states
ProjectImportState.with_status([:scheduled, :started])
2017-08-17 22:00:37 +05:30
end
2018-12-05 23:21:45 +05:30
# rubocop: disable CodeReuse/ActiveRecord
2018-12-13 13:39:08 +05:30
def enqueued_import_states_with_jid
enqueued_import_states.where.not(jid: nil)
2018-03-17 18:26:18 +05:30
end
2018-12-05 23:21:45 +05:30
# rubocop: enable CodeReuse/ActiveRecord
2017-08-17 22:00:37 +05:30
2018-12-05 23:21:45 +05:30
# rubocop: disable CodeReuse/ActiveRecord
2018-12-13 13:39:08 +05:30
def enqueued_import_states_without_jid
enqueued_import_states.where(jid: nil)
2017-08-17 22:00:37 +05:30
end
2018-12-05 23:21:45 +05:30
# rubocop: enable CodeReuse/ActiveRecord
2017-08-17 22:00:37 +05:30
def error_message
2019-02-15 15:39:39 +05:30
_("Import timed out. Import took longer than %{import_jobs_expiration} seconds") % { import_jobs_expiration: IMPORT_JOBS_EXPIRATION }
2017-08-17 22:00:37 +05:30
end
end