Commit 43a359ab authored by Douwe Maan's avatar Douwe Maan

Verify project import status again before marking as failed

parent e610f960
...@@ -22,25 +22,23 @@ class StuckImportJobsWorker ...@@ -22,25 +22,23 @@ class StuckImportJobsWorker
end end
def mark_projects_with_jid_as_failed! def mark_projects_with_jid_as_failed!
completed_jids_count = 0 jids_and_ids = enqueued_projects_with_jid.pluck(:import_jid, :id).to_h
enqueued_projects_with_jid.find_in_batches(batch_size: 500) do |group| # Find the jobs that aren't currently running or that exceeded the threshold.
jids = group.map(&:import_jid) completed_jids = Gitlab::SidekiqStatus.completed_jids(jids_and_ids.keys)
return unless completed_jids.any?
# Find the jobs that aren't currently running or that exceeded the threshold. completed_project_ids = jids_and_ids.values_at(*completed_jids)
completed_jids = Gitlab::SidekiqStatus.completed_jids(jids).to_set
if completed_jids.any? # We select the projects again, because they may have transitioned from
completed_jids_count += completed_jids.count # scheduled/started to finished/failed while we were looking up their Sidekiq status.
group.each do |project| completed_projects = enqueued_projects_with_jid.where(id: completed_project_ids)
project.mark_import_as_failed(error_message) if completed_jids.include?(project.import_jid)
end
Rails.logger.info("Marked stuck import jobs as failed. JIDs: #{completed_jids.to_a.join(', ')}") Rails.logger.info("Marked stuck import jobs as failed. JIDs: #{completed_projects.map(&:import_jid).join(', ')}")
end
end
completed_jids_count completed_projects.each do |project|
project.mark_import_as_failed(error_message)
end.count
end end
def enqueued_projects def enqueued_projects
......
---
title: Verify project import status again before marking as failed
merge_request:
author:
type: fixed
...@@ -2,32 +2,46 @@ require 'spec_helper' ...@@ -2,32 +2,46 @@ require 'spec_helper'
describe StuckImportJobsWorker do describe StuckImportJobsWorker do
let(:worker) { described_class.new } let(:worker) { described_class.new }
let(:exclusive_lease_uuid) { SecureRandom.uuid }
before do
allow_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain).and_return(exclusive_lease_uuid)
end
shared_examples 'project import job detection' do shared_examples 'project import job detection' do
describe 'long running import' do context 'when the job has completed' do
it 'marks the project as failed' do context 'when the import status was already updated' do
allow(Gitlab::SidekiqStatus).to receive(:completed_jids).and_return(['123']) before do
allow(Gitlab::SidekiqStatus).to receive(:completed_jids) do
project.import_start
project.import_finish
[project.import_jid]
end
end
expect { worker.perform }.to change { project.reload.import_status }.to('failed') it 'does not mark the project as failed' do
worker.perform
expect(project.reload.import_status).to eq('finished')
end
end
context 'when the import status was not updated' do
before do
allow(Gitlab::SidekiqStatus).to receive(:completed_jids).and_return([project.import_jid])
end
it 'marks the project as failed' do
worker.perform
expect(project.reload.import_status).to eq('failed')
end
end end
end end
describe 'running import' do context 'when the job is still in Sidekiq' do
it 'does not mark the project as failed' do before do
allow(Gitlab::SidekiqStatus).to receive(:completed_jids).and_return([]) allow(Gitlab::SidekiqStatus).to receive(:completed_jids).and_return([])
expect { worker.perform }.not_to change { project.reload.import_status }
end end
describe 'import without import_jid' do it 'does not mark the project as failed' do
it 'marks the project as failed' do expect { worker.perform }.not_to change { project.reload.import_status }
expect { worker.perform }.to change { project.reload.import_status }.to('failed')
end
end end
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment