Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean McGivern <sean@gitlab.com>2018-04-20 20:37:38 +0300
committerSean McGivern <sean@gitlab.com>2018-04-25 14:48:14 +0300
commitb5042e5301e86ec7822221ee29679b0fbf5c71ca (patch)
tree48d02d3b6b52c94015d5bb6509db3807056e3dff /spec/workers/mail_scheduler
parentfd532302ecb04159ce1299f1b312fe622147849c (diff)
Move NotificationService calls to Sidekiq
The NotificationService has to do quite a lot of work to calculate the recipients for an email. Where possible, we should try to avoid doing this in an HTTP request, because the mail are sent by Sidekiq anyway, so there's no need to schedule those emails immediately. This commit creates a generic Sidekiq worker that uses Global ID to serialise and deserialise its arguments, then forwards them to the NotificationService. The NotificationService gains an `#async` method, so you can replace: notification_service.new_issue(issue, current_user) With: notification_service.async.new_issue(issue, current_user) And have everything else work as normal, except that calculating the recipients will be done by Sidekiq, which will then schedule further Sidekiq jobs to send each email.
Diffstat (limited to 'spec/workers/mail_scheduler')
-rw-r--r--spec/workers/mail_scheduler/issue_due_worker_spec.rb4
-rw-r--r--spec/workers/mail_scheduler/notification_service_worker_spec.rb44
2 files changed, 46 insertions, 2 deletions
diff --git a/spec/workers/mail_scheduler/issue_due_worker_spec.rb b/spec/workers/mail_scheduler/issue_due_worker_spec.rb
index 48ac1b8a1a4..1026ae5b4bf 100644
--- a/spec/workers/mail_scheduler/issue_due_worker_spec.rb
+++ b/spec/workers/mail_scheduler/issue_due_worker_spec.rb
@@ -12,8 +12,8 @@ describe MailScheduler::IssueDueWorker do
create(:issue, :opened, project: project, due_date: 2.days.from_now) # due on another day
create(:issue, :opened, due_date: Date.tomorrow) # different project
- expect_any_instance_of(NotificationService).to receive(:issue_due).with(issue1)
- expect_any_instance_of(NotificationService).to receive(:issue_due).with(issue2)
+ expect(worker.notification_service).to receive(:issue_due).with(issue1)
+ expect(worker.notification_service).to receive(:issue_due).with(issue2)
worker.perform(project.id)
end
diff --git a/spec/workers/mail_scheduler/notification_service_worker_spec.rb b/spec/workers/mail_scheduler/notification_service_worker_spec.rb
new file mode 100644
index 00000000000..f725c8763a0
--- /dev/null
+++ b/spec/workers/mail_scheduler/notification_service_worker_spec.rb
@@ -0,0 +1,44 @@
+require 'spec_helper'
+
+describe MailScheduler::NotificationServiceWorker do
+ let(:worker) { described_class.new }
+ let(:method) { 'new_key' }
+ set(:key) { create(:personal_key) }
+
+ def serialize(*args)
+ ActiveJob::Arguments.serialize(args)
+ end
+
+ describe '#perform' do
+ it 'deserializes arguments from global IDs' do
+ expect(worker.notification_service).to receive(method).with(key)
+
+ worker.perform(method, *serialize(key))
+ end
+
+ context 'when the arguments cannot be deserialized' do
+ it 'does nothing' do
+ expect(worker.notification_service).not_to receive(method)
+
+ worker.perform(method, key.to_global_id.to_s.succ)
+ end
+ end
+
+ context 'when the method is not a public method' do
+ it 'raises NoMethodError' do
+ expect { worker.perform('notifiable?', *serialize(key)) }.to raise_error(NoMethodError)
+ end
+ end
+ end
+
+ describe '.perform_async' do
+ it 'serializes arguments as global IDs when scheduling' do
+ Sidekiq::Testing.fake! do
+ described_class.perform_async(method, key)
+
+ expect(described_class.jobs.count).to eq(1)
+ expect(described_class.jobs.first).to include('args' => [method, *serialize(key)])
+ end
+ end
+ end
+end