Commit bd825bf9 authored by Grzegorz Bizon's avatar Grzegorz Bizon

Merge branch 'batched-minutes-reset' into 'master'

Batching minutes reset queries in ClearSharedRunnersMinutesWorker

See merge request gitlab-org/gitlab-ee!15002
parents 44c031db aac514ee
......@@ -42,6 +42,15 @@ module EE
scope :with_plan, -> { where.not(plan_id: nil) }
scope :with_shared_runners_minutes_limit, -> { where("namespaces.shared_runners_minutes_limit > 0") }
scope :with_extra_shared_runners_minutes_limit, -> { where("namespaces.extra_shared_runners_minutes_limit > 0") }
scope :with_shared_runners_minutes_exceeding_default_limit, -> do
where('namespace_statistics.namespace_id = namespaces.id')
.where('namespace_statistics.shared_runners_seconds > (namespaces.shared_runners_minutes_limit * 60)')
end
scope :with_ci_minutes_notification_sent, -> do
where('last_ci_minutes_notification_at IS NOT NULL OR last_ci_minutes_usage_notification_level IS NOT NULL')
end
scope :with_feature_available_in_plan, -> (feature) do
plans = plans_with_feature(feature)
matcher = Plan.where(name: plans)
......
......@@ -6,35 +6,34 @@ class ClearSharedRunnersMinutesWorker
include ApplicationWorker
include CronjobQueue
# rubocop: disable CodeReuse/ActiveRecord
def perform
return unless try_obtain_lease
Namespace.with_shared_runners_minutes_limit
.with_extra_shared_runners_minutes_limit
.where('namespace_statistics.namespace_id = namespaces.id')
.where('namespace_statistics.shared_runners_seconds > (namespaces.shared_runners_minutes_limit * 60)')
.with_shared_runners_minutes_exceeding_default_limit
.update_all("extra_shared_runners_minutes_limit = #{extra_minutes_left_sql} FROM namespace_statistics")
Namespace.where('last_ci_minutes_notification_at IS NOT NULL OR last_ci_minutes_usage_notification_level IS NOT NULL')
.each_batch do |relation|
relation.update_all(last_ci_minutes_notification_at: nil, last_ci_minutes_usage_notification_level: nil)
Namespace.with_ci_minutes_notification_sent.each_batch do |namespaces|
Namespace.transaction do
reset_statistics(NamespaceStatistics, namespaces)
reset_statistics(ProjectStatistics, namespaces)
namespaces.update_all(last_ci_minutes_notification_at: nil, last_ci_minutes_usage_notification_level: nil)
end
end
end
NamespaceStatistics.where.not(shared_runners_seconds: 0)
.update_all(
shared_runners_seconds: 0,
shared_runners_seconds_last_reset: Time.now)
private
ProjectStatistics.where.not(shared_runners_seconds: 0)
.update_all(
shared_runners_seconds: 0,
shared_runners_seconds_last_reset: Time.now)
# rubocop: disable CodeReuse/ActiveRecord
def reset_statistics(model, namespaces)
model.where(namespace: namespaces).where.not(shared_runners_seconds: 0).update_all(
shared_runners_seconds: 0,
shared_runners_seconds_last_reset: Time.now)
end
# rubocop: enable CodeReuse/ActiveRecord
private
def extra_minutes_left_sql
"GREATEST((namespaces.shared_runners_minutes_limit + namespaces.extra_shared_runners_minutes_limit) - ROUND(namespace_statistics.shared_runners_seconds / 60.0), 0)"
end
......
---
title: Batching minutes reset queries to avoid query timeouts
merge_request: 15002
author:
type: fixed
......@@ -4,6 +4,8 @@ describe ClearSharedRunnersMinutesWorker do
let(:worker) { described_class.new }
describe '#perform' do
let(:namespace) { create(:namespace, last_ci_minutes_notification_at: Time.now) }
before do
expect_any_instance_of(described_class)
.to receive(:try_obtain_lease).and_return(true)
......@@ -12,7 +14,7 @@ describe ClearSharedRunnersMinutesWorker do
subject { worker.perform }
context 'when project statistics are defined' do
let(:project) { create(:project) }
let(:project) { create(:project, namespace: namespace) }
let(:statistics) { project.statistics }
before do
......@@ -33,7 +35,7 @@ describe ClearSharedRunnersMinutesWorker do
end
context 'when namespace statistics are defined' do
let!(:statistics) { create(:namespace_statistics, shared_runners_seconds: 100) }
let!(:statistics) { create(:namespace_statistics, namespace: namespace, shared_runners_seconds: 100) }
it 'clears counters' do
subject
......
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