Commit 78116ae3 authored by Sean Arnold's avatar Sean Arnold

Move escalation creation into background job

- Add new worker
- update queue files
parent 2aad4222
...@@ -184,6 +184,8 @@ ...@@ -184,6 +184,8 @@
- 1 - 1
- - incident_management_pending_escalations_alert_check - - incident_management_pending_escalations_alert_check
- 1 - 1
- - incident_management_pending_escalations_alert_create
- 1
- - invalid_gpg_signature_update - - invalid_gpg_signature_update
- 2 - 2
- - irker - - irker
......
...@@ -45,7 +45,7 @@ module EE ...@@ -45,7 +45,7 @@ module EE
end end
def create_pending_escalations def create_pending_escalations
::IncidentManagement::PendingEscalations::CreateService.new(alert).execute ::IncidentManagement::PendingEscalations::AlertCreateWorker.perform_async(alert.id)
end end
end end
end end
......
...@@ -25,7 +25,7 @@ module EE ...@@ -25,7 +25,7 @@ module EE
end end
def create_pending_escalations def create_pending_escalations
::IncidentManagement::PendingEscalations::CreateService.new(alert).execute ::IncidentManagement::PendingEscalations::AlertCreateWorker.perform_async(alert.id)
end end
end end
end end
......
...@@ -34,9 +34,6 @@ module IncidentManagement ...@@ -34,9 +34,6 @@ module IncidentManagement
end end
process_escalations(escalation_ids) process_escalations(escalation_ids)
rescue StandardError => e
Gitlab::ErrorTracking.track_exception(e, target_type: target.class.to_s, target_id: target.id)
end end
def create_escalation(rule) def create_escalation(rule)
......
...@@ -12,6 +12,7 @@ module IncidentManagement ...@@ -12,6 +12,7 @@ module IncidentManagement
def execute def execute
return unless ::Gitlab::IncidentManagement.escalation_policies_available?(project) return unless ::Gitlab::IncidentManagement.escalation_policies_available?(project)
return if too_early_to_process?
return if target_already_resolved? return if target_already_resolved?
return if target_status_exceeded_rule? return if target_status_exceeded_rule?
...@@ -33,6 +34,10 @@ module IncidentManagement ...@@ -33,6 +34,10 @@ module IncidentManagement
target.status >= escalation.status_before_type_cast target.status >= escalation.status_before_type_cast
end end
def too_early_to_process?
Time.current < escalation.process_at
end
def notify_recipients def notify_recipients
NotificationService NotificationService
.new .new
......
...@@ -1072,6 +1072,15 @@ ...@@ -1072,6 +1072,15 @@
:weight: 1 :weight: 1
:idempotent: true :idempotent: true
:tags: [] :tags: []
- :name: incident_management_pending_escalations_alert_create
:worker_name: IncidentManagement::PendingEscalations::AlertCreateWorker
:feature_category: :incident_management
:has_external_dependencies:
:urgency: :high
:resource_boundary: :unknown
:weight: 1
:idempotent: true
:tags: []
- :name: ldap_group_sync - :name: ldap_group_sync
:worker_name: LdapGroupSyncWorker :worker_name: LdapGroupSyncWorker
:feature_category: :authentication_and_authorization :feature_category: :authentication_and_authorization
......
# frozen_string_literal: true
module IncidentManagement
module PendingEscalations
class AlertCreateWorker
include ApplicationWorker
urgency :high
idempotent!
feature_category :incident_management
def perform(alert_id)
alert = ::AlertManagement::Alert.find(alert_id)
::IncidentManagement::PendingEscalations::CreateService.new(alert).execute
end
end
end
end
...@@ -33,10 +33,7 @@ RSpec.describe AlertManagement::Alerts::UpdateService do ...@@ -33,10 +33,7 @@ RSpec.describe AlertManagement::Alerts::UpdateService do
let(:new_status) { :triggered } let(:new_status) { :triggered }
it 'creates an escalation' do it_behaves_like 'creates an escalation'
expect { execute }.to change { IncidentManagement::PendingEscalations::Alert.count }.by(1)
expect(IncidentManagement::PendingEscalations::Alert.last.alert).to eq(alert)
end
end end
context 'moving from an open status to closed status' do context 'moving from an open status to closed status' do
......
...@@ -14,7 +14,8 @@ RSpec.describe IncidentManagement::PendingEscalations::ProcessService do ...@@ -14,7 +14,8 @@ RSpec.describe IncidentManagement::PendingEscalations::ProcessService do
let(:alert_params) { { status: AlertManagement::Alert::STATUSES[:triggered] } } let(:alert_params) { { status: AlertManagement::Alert::STATUSES[:triggered] } }
let(:target) { alert } let(:target) { alert }
let(:escalation) { create(:incident_management_pending_alert_escalation, rule: escalation_rule, oncall_schedule: schedule_1, target: target, status: IncidentManagement::EscalationRule.statuses[:acknowledged]) } let(:process_at) { 5.minutes.ago }
let(:escalation) { create(:incident_management_pending_alert_escalation, rule: escalation_rule, oncall_schedule: schedule_1, target: target, status: IncidentManagement::EscalationRule.statuses[:acknowledged], process_at: process_at) }
let(:service) { described_class.new(escalation) } let(:service) { described_class.new(escalation) }
...@@ -70,5 +71,11 @@ RSpec.describe IncidentManagement::PendingEscalations::ProcessService do ...@@ -70,5 +71,11 @@ RSpec.describe IncidentManagement::PendingEscalations::ProcessService do
it_behaves_like 'it does not escalate' it_behaves_like 'it does not escalate'
end end
context 'escalation is not ready to be processed' do
let(:process_at) { 5.minutes.from_now }
it_behaves_like 'it does not escalate'
end
end end
end end
...@@ -105,7 +105,7 @@ RSpec.describe Projects::Alerting::NotifyService do ...@@ -105,7 +105,7 @@ RSpec.describe Projects::Alerting::NotifyService do
end end
it_behaves_like 'does not send on-call notification' it_behaves_like 'does not send on-call notification'
include_examples 'creates an escalation', 1 include_examples 'creates an escalation'
context 'existing alert with same payload fingerprint' do context 'existing alert with same payload fingerprint' do
let_it_be(:alert) { create(:alert_management_alert, fingerprint: gitlab_fingerprint, project: project) } let_it_be(:alert) { create(:alert_management_alert, fingerprint: gitlab_fingerprint, project: project) }
......
# frozen_string_literal: true # frozen_string_literal: true
RSpec.shared_examples 'creates an escalation' do |count| RSpec.shared_examples 'creates an escalation' do
let(:count) { count }
specify do specify do
expect(IncidentManagement::PendingEscalations::Alert).to receive(:create!) expect(IncidentManagement::PendingEscalations::AlertCreateWorker)
.with(target: a_kind_of(AlertManagement::Alert), rule: a_kind_of(IncidentManagement::EscalationRule), schedule_id: a_kind_of(Integer), status: a_kind_of(String), process_at: a_kind_of(ActiveSupport::TimeWithZone)) .to receive(:perform_async)
.exactly(count).times .with(a_kind_of(Integer))
.and_call_original
expected_args = []
count.times { expected_args << [a_kind_of(Integer)]}
expect(IncidentManagement::PendingEscalations::AlertCheckWorker)
.to receive(:bulk_perform_async)
.with(expected_args)
subject subject
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