diff options
author | Mayra Cabrera <mcabrera@gitlab.com> | 2019-07-03 08:58:13 -0500 |
---|---|---|
committer | Mayra Cabrera <mcabrera@gitlab.com> | 2019-07-04 08:23:13 -0500 |
commit | f3a91d9d634f920f60ff9a026896f47ee2c768cd (patch) | |
tree | 0dec3191b3bb3e04f0d5abdfe10a9d0dca73068b | |
parent | db26cddaaae20655776e6fac31b29e67b5edfa2e (diff) | |
download | gitlab-ce-64079-aggregation-schedule-should-keep-lease-until-timeout.tar.gz |
Implements lease_release on NamespaceAggregation64079-aggregation-schedule-should-keep-lease-until-timeout
Sets lease_release? to false to prevent the job to be re-executed more
often than lease timeout
Closes https://gitlab.com/gitlab-org/gitlab-ce/issues/64079
-rw-r--r-- | app/models/namespace/aggregation_schedule.rb | 8 | ||||
-rw-r--r-- | spec/models/namespace/aggregation_schedule_spec.rb | 31 | ||||
-rw-r--r-- | spec/workers/namespaces/schedule_aggregation_worker_spec.rb | 39 |
3 files changed, 63 insertions, 15 deletions
diff --git a/app/models/namespace/aggregation_schedule.rb b/app/models/namespace/aggregation_schedule.rb index 355593597c6..0bef352cf24 100644 --- a/app/models/namespace/aggregation_schedule.rb +++ b/app/models/namespace/aggregation_schedule.rb @@ -44,4 +44,12 @@ class Namespace::AggregationSchedule < ApplicationRecord def lease_key "namespace:namespaces_root_statistics:#{namespace_id}" end + + # Used by ExclusiveLeaseGuard + # Overriding value as we never release the lease + # before the timeout in order to prevent multiple + # RootStatisticsWorker to start in a short span of time + def lease_release? + false + end end diff --git a/spec/models/namespace/aggregation_schedule_spec.rb b/spec/models/namespace/aggregation_schedule_spec.rb index 8ed0248e1b2..0f1283717e0 100644 --- a/spec/models/namespace/aggregation_schedule_spec.rb +++ b/spec/models/namespace/aggregation_schedule_spec.rb @@ -53,10 +53,39 @@ RSpec.describe Namespace::AggregationSchedule, :clean_gitlab_redis_shared_state, expect(Namespaces::RootStatisticsWorker) .to receive(:perform_in).once - .with(described_class::DEFAULT_LEASE_TIMEOUT, aggregation_schedule.namespace_id ) + .with(described_class::DEFAULT_LEASE_TIMEOUT, aggregation_schedule.namespace_id) aggregation_schedule.save! end + + it 'does not release the lease' do + stub_exclusive_lease(lease_key, timeout: described_class::DEFAULT_LEASE_TIMEOUT) + + aggregation_schedule.save! + + exclusive_lease = aggregation_schedule.exclusive_lease + expect(exclusive_lease.exists?).to be_truthy + end + + it 'only executes the workers once' do + # Avoid automatic deletion of Namespace::AggregationSchedule + # for testing purposes. + expect(Namespaces::RootStatisticsWorker) + .to receive(:perform_async).once + .and_return(nil) + + expect(Namespaces::RootStatisticsWorker) + .to receive(:perform_in).once + .with(described_class::DEFAULT_LEASE_TIMEOUT, aggregation_schedule.namespace_id) + .and_return(nil) + + # Scheduling workers for the first time + aggregation_schedule.schedule_root_storage_statistics + + # Executing again, this time workers should not be scheduled + # due to the lease not been released. + aggregation_schedule.schedule_root_storage_statistics + end end context 'with a personalized lease timeout' do diff --git a/spec/workers/namespaces/schedule_aggregation_worker_spec.rb b/spec/workers/namespaces/schedule_aggregation_worker_spec.rb index 7432ca12f2a..d4a49a3f53a 100644 --- a/spec/workers/namespaces/schedule_aggregation_worker_spec.rb +++ b/spec/workers/namespaces/schedule_aggregation_worker_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -describe Namespaces::ScheduleAggregationWorker, '#perform' do +describe Namespaces::ScheduleAggregationWorker, '#perform', :clean_gitlab_redis_shared_state do let(:group) { create(:group) } subject(:worker) { described_class.new } @@ -10,6 +10,8 @@ describe Namespaces::ScheduleAggregationWorker, '#perform' do context 'when group is the root ancestor' do context 'when aggregation schedule exists' do it 'does not create a new one' do + stub_aggregation_schedule_statistics + Namespace::AggregationSchedule.safe_find_or_create_by!(namespace_id: group.id) expect do @@ -18,26 +20,25 @@ describe Namespaces::ScheduleAggregationWorker, '#perform' do end end - context 'when update_statistics_namespace is off' do - it 'does not create a new one' do - stub_feature_flags(update_statistics_namespace: false, namespace: group) + context 'when aggregation schedule does not exist' do + it 'creates one' do + stub_aggregation_schedule_statistics expect do worker.perform(group.id) - end.not_to change(Namespace::AggregationSchedule, :count) + end.to change(Namespace::AggregationSchedule, :count).by(1) + + expect(group.aggregation_schedule).to be_present end end - context 'when aggregation schedule does not exist' do - it 'creates one' do - allow_any_instance_of(Namespace::AggregationSchedule) - .to receive(:schedule_root_storage_statistics).and_return(nil) + context 'when update_statistics_namespace is off' do + it 'does not create a new one' do + stub_feature_flags(update_statistics_namespace: false, namespace: group) expect do worker.perform(group.id) - end.to change(Namespace::AggregationSchedule, :count).by(1) - - expect(group.aggregation_schedule).to be_present + end.not_to change(Namespace::AggregationSchedule, :count) end end end @@ -47,8 +48,7 @@ describe Namespaces::ScheduleAggregationWorker, '#perform' do let(:group) { create(:group, parent: parent_group) } it 'creates an aggregation schedule for the root' do - allow_any_instance_of(Namespace::AggregationSchedule) - .to receive(:schedule_root_storage_statistics).and_return(nil) + stub_aggregation_schedule_statistics worker.perform(group.id) @@ -63,4 +63,15 @@ describe Namespaces::ScheduleAggregationWorker, '#perform' do worker.perform(12345) end end + + def stub_aggregation_schedule_statistics + # Namespace::Aggregations are deleted by + # Namespace::AggregationSchedule::schedule_root_storage_statistics, + # which is executed async. Stubing the service so instances are not deleted + # while still running the specs. + expect_next_instance_of(Namespace::AggregationSchedule) do |aggregation_schedule| + expect(aggregation_schedule) + .to receive(:schedule_root_storage_statistics) + end + end end |