Commit 7648c9c8 authored by Mike Kozono's avatar Mike Kozono

Prevent sync if excluded by selective sync

of design repositories. Not only should we not enqueue a sync
job, but we need to not create a registry.
parent aed403db
......@@ -9,8 +9,10 @@ module Gitlab
def process
job_id =
unless skippable?
if replicable_project?(event.project_id)
registry.repository_updated!
registry.save
schedule_job(event)
end
......@@ -20,7 +22,7 @@ module Gitlab
private
def registry
@registry ||= ::Geo::DesignRegistry.safe_find_or_create_by(project_id: event.project_id)
@registry ||= ::Geo::DesignRegistry.find_or_initialize_by(project_id: event.project_id) # rubocop: disable CodeReuse/ActiveRecord
end
def schedule_job(event)
......@@ -34,7 +36,7 @@ module Gitlab
'Design repository update',
project_id: event.project_id,
scheduled_at: Time.now,
skippable: skippable?,
replicable_project: replicable_project?(event.project_id),
job_id: job_id)
end
end
......
......@@ -6,47 +6,58 @@ RSpec.describe Gitlab::Geo::LogCursor::Events::DesignRepositoryUpdatedEvent, :cl
include ::EE::GeoHelpers
let_it_be(:secondary) { create(:geo_node) }
let_it_be(:secondary_excludes_all_projects) { create(:geo_node, :selective_sync_excludes_all_projects) }
let(:logger) { Gitlab::Geo::LogCursor::Logger.new(described_class, Logger::INFO) }
let(:project) { create(:project) }
let(:event) { create(:geo_design_repository_updated_event, project: project) }
let(:event_log) { create(:geo_event_log, repository_updated_event: event) }
let(:design_repository_updated_event) { create(:geo_design_repository_updated_event, project: project) }
let(:event_log) { create(:geo_event_log, repository_updated_event: design_repository_updated_event) }
let!(:event_log_state) { create(:geo_event_log_state, event_id: event_log.id - 1) }
let(:sync_worker_class) { ::Geo::DesignRepositorySyncWorker }
let(:registry_class) { ::Geo::DesignRegistry }
let(:registry_factory) { :geo_design_registry }
let(:registry_factory_args) { [:synced, project: project] }
let(:sync_worker_expected_arg) { project.id }
subject { described_class.new(event, Time.now, logger) }
around do |example|
Sidekiq::Testing.fake! { example.run }
end
subject(:event) { described_class.new(design_repository_updated_event, Time.now, logger) }
before do
stub_current_geo_node(secondary)
end
shared_examples 'DesignRepositoryUpdatedEvent' do
it 'creates a new registry when a design registry does not exist' do
expect { subject.process }.to change(Geo::DesignRegistry, :count).by(1)
end
it 'marks registry as pending when a design registry exists' do
registry = create(:geo_design_registry, :synced, project: project)
expect { subject.process }.to change { registry.reload.state }.from('synced').to('pending')
end
end
describe '#process' do
context 'when the associated shard is healthy' do
before do
allow(Gitlab::ShardHealthCache).to receive(:healthy_shard?).with('default').and_return(true)
end
it_behaves_like 'DesignRepositoryUpdatedEvent'
it 'schedules a Geo::DesignRepositorySyncWorker' do
expect(Geo::DesignRepositorySyncWorker).to receive(:perform_async).with(project.id).once
context "when the container repository's project is not excluded by selective sync" do
it_behaves_like 'event should trigger a sync'
end
subject.process
context "when the container repository's project is excluded by selective sync" do
before do
stub_current_geo_node(secondary_excludes_all_projects)
end
context 'when a registry does not yet exist' do
it_behaves_like 'event does not create a registry'
it_behaves_like 'event does not schedule a sync worker'
it_behaves_like 'logs event source info'
end
# This describes an optimization to avoid double-checking a heavy (330ms
# is heavy for the log cursor) selective sync query too often:
# If the registry exists, then we assume it *should* exist. This will
# usually be accurate. The responsibility falls to proper handling of
# delete events as well as the `RegistryConsistencyWorker` to remove
# registries.
context 'when a registry exists' do
let!(:registry) { create(registry_factory, *registry_factory_args) }
it_behaves_like 'event transitions a registry to pending'
it_behaves_like 'event schedules a sync worker'
it_behaves_like 'logs event source info'
end
end
end
......@@ -55,15 +66,19 @@ RSpec.describe Gitlab::Geo::LogCursor::Events::DesignRepositoryUpdatedEvent, :cl
allow(Gitlab::ShardHealthCache).to receive(:healthy_shard?).with('default').and_return(false)
end
it_behaves_like 'DesignRepositoryUpdatedEvent'
context 'when a registry does not yet exist' do
it_behaves_like 'event creates a registry'
it_behaves_like 'event does not schedule a sync worker'
it_behaves_like 'logs event source info'
end
it 'does not schedule a Geo::DesignRepositorySyncWorker job' do
expect(Geo::DesignRepositorySyncWorker).not_to receive(:perform_async).with(project.id)
context 'when a registry exists' do
let!(:registry) { create(registry_factory, *registry_factory_args) }
subject.process
it_behaves_like 'event transitions a registry to pending'
it_behaves_like 'event does not schedule a sync worker'
it_behaves_like 'logs event source info'
end
end
it_behaves_like 'logs event source info'
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