Commit 6c0dea86 authored by Michael Kozono's avatar Michael Kozono

Merge branch '34324-scheduling-the-design-repositories-sync' into 'master'

Geo - Scheduling the design repositories sync

See merge request gitlab-org/gitlab!19890
parents 5969e47e 17749b18
......@@ -19,5 +19,9 @@ module Geo
::Gitlab::Database::Subquery.self_join(limit(limit)).delete_all
end
end
def consumer_klass_name
self.class.name.demodulize
end
end
end
......@@ -2,6 +2,7 @@
module Geo
class RepositoryUpdatedEvent < ApplicationRecord
extend ::Gitlab::Utils::Override
include Geo::Model
include Geo::Eventable
......@@ -24,5 +25,14 @@ module Geo
def self.source_for(repository)
REPOSITORY_TYPE_MAP[repository.repo_type]
end
override :consumer_klass_name
def consumer_klass_name
if design?
::Gitlab::Geo::LogCursor::Events::DesignRepositoryUpdatedEvent.name.demodulize
else
super
end
end
end
end
......@@ -16,10 +16,7 @@ module Geo
def execute
return false unless Gitlab::Geo.primary?
if source == Geo::RepositoryUpdatedEvent::DESIGN && Feature.disabled?(:enable_geo_design_sync)
return false
end
return false if design? && Feature.disabled?(:enable_geo_design_sync)
reset_repository_checksum!
create_repository_updated_event!
......@@ -39,10 +36,13 @@ module Geo
).create!
end
def design?
source == Geo::RepositoryUpdatedEvent::DESIGN
end
def reset_repository_checksum!
# We don't yet support verification for Design repositories
return if source == Geo::RepositoryUpdatedEvent::DESIGN
return if design?
return if repository_state.nil?
repository_state.update!(
......
......@@ -114,7 +114,7 @@ module Gitlab
end
def event_klass_for(event)
event_klass_name = event.class.name.demodulize
event_klass_name = event.consumer_klass_name
current_namespace = self.class.name.deconstantize
Object.const_get("#{current_namespace}::Events::#{event_klass_name}", false)
end
......
# frozen_string_literal: true
module Gitlab
module Geo
module LogCursor
module Events
class DesignRepositoryUpdatedEvent
include BaseEvent
def process
job_id =
unless skippable?
registry.repository_updated!
schedule_job(event)
end
log_event(job_id)
end
private
def registry
@registry ||= ::Geo::DesignRegistry.safe_find_or_create_by(project_id: event.project_id)
end
def schedule_job(event)
enqueue_job_if_shard_healthy(event) do
::Geo::DesignRepositorySyncWorker.perform_async(event.project_id)
end
end
def skippable?
Feature.disabled?(:enable_geo_design_sync)
end
def log_event(job_id)
logger.event_info(
created_at,
'Design repository update',
project_id: event.project_id,
scheduled_at: Time.now,
skippable: skippable?,
job_id: job_id)
end
end
end
end
end
end
......@@ -49,6 +49,10 @@ FactoryBot.define do
trait :container_repository_updated_event do
container_repository_updated_event factory: :geo_container_repository_updated_event
end
trait :design_repository_updated_event do
repository_updated_event factory: :geo_design_repository_updated_event
end
end
factory :geo_repository_created_event, class: Geo::RepositoryCreatedEvent do
......@@ -63,7 +67,15 @@ FactoryBot.define do
factory :geo_repository_updated_event, class: Geo::RepositoryUpdatedEvent do
project
source { 0 }
source { Geo::RepositoryUpdatedEvent::REPOSITORY }
branches_affected { 0 }
tags_affected { 0 }
end
factory :geo_design_repository_updated_event, class: Geo::RepositoryUpdatedEvent do
project
source { Geo::RepositoryUpdatedEvent::DESIGN }
branches_affected { 0 }
tags_affected { 0 }
end
......
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::Geo::LogCursor::Events::DesignRepositoryUpdatedEvent, :clean_gitlab_redis_shared_state do
include ::EE::GeoHelpers
let_it_be(:secondary) { create(:geo_node) }
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!(:event_log_state) { create(:geo_event_log_state, event_id: event_log.id - 1) }
subject { described_class.new(event, Time.now, logger) }
around do |example|
Sidekiq::Testing.fake! { example.run }
end
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 feature flag is disabled' do
before do
stub_feature_flags(enable_geo_design_sync: false)
end
it 'does not create a design registry' do
expect { subject.process }.not_to change(Geo::DesignRegistry, :count)
end
it 'does not schedule a Geo::DesignRepositorySyncWorker job' do
expect(Geo::DesignRepositorySyncWorker).not_to receive(:perform_async).with(project.id)
subject.process
end
end
context 'when the feature flag is disabled' do
before do
stub_feature_flags(enable_geo_design_sync: true)
end
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
subject.process
end
end
context 'when associated shard is unhealthy' do
before do
allow(Gitlab::ShardHealthCache).to receive(:healthy_shard?).with('default').and_return(false)
end
it_behaves_like 'DesignRepositoryUpdatedEvent'
it 'does not schedule a Geo::DesignRepositorySyncWorker job' do
expect(Geo::DesignRepositorySyncWorker).not_to receive(:perform_async).with(project.id)
subject.process
end
end
end
end
end
......@@ -20,4 +20,12 @@ RSpec.describe Geo::Eventable do
end.to change { Geo::RepositoryUpdatedEvent.count }.by(-2)
end
end
describe '#consumer_klass_name' do
it 'returns the even class name without the module part' do
event = build(:geo_repository_created_event)
expect(event.consumer_klass_name).to eq 'RepositoryCreatedEvent'
end
end
end
......@@ -11,7 +11,25 @@ RSpec.describe Geo::RepositoryUpdatedEvent, type: :model do
it { is_expected.to validate_presence_of(:project) }
end
describe '#consumer_klass_name' do
using RSpec::Parameterized::TableSyntax
where(:source, :consumer_klass_name) do
:design | 'DesignRepositoryUpdatedEvent'
:repository | 'RepositoryUpdatedEvent'
:wiki | 'RepositoryUpdatedEvent'
end
with_them do
it 'returns the proper consumer class name' do
subject.source = source
expect(subject.consumer_klass_name).to eq consumer_klass_name
end
end
end
describe '#source' do
it { is_expected.to define_enum_for(:source).with([:repository, :wiki, :design]) }
it { is_expected.to define_enum_for(:source).with_values([:repository, :wiki, :design]) }
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