summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2016-01-29 13:51:34 +0000
committerDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2016-01-29 13:51:34 +0000
commit227728712ec5b469a36dbaf8c9511098b4817741 (patch)
treee443174f1322c3970fbd1f67b7b18ec95ef1fe44
parente221990ebac72b8b229b8c3ff38069edbf7776a7 (diff)
parentf3d4f2eac7bcf787a00a6cff694fbfa8969830f4 (diff)
downloadgitlab-ce-227728712ec5b469a36dbaf8c9511098b4817741.tar.gz
Merge branch 'note-background-job' into 'master'
Background process note logic for #3948 Quick and dirty way to get *most* of the note processing out of band and into the background. Seeing some pretty nice speed bumps. Keep in mind that doing this in process results in slower and slower responses as more notes are added and more participants exist. ``` without background processing Completed 200 OK in 627ms (Views: 0.5ms | ActiveRecord: 32.3ms) Completed 200 OK in 478ms (Views: 0.8ms | ActiveRecord: 28.3ms) Completed 200 OK in 1107ms (Views: 0.6ms | ActiveRecord: 36.6ms) with background processing Completed 200 OK in 108ms (Views: 0.6ms | ActiveRecord: 4.7ms) Completed 200 OK in 78ms (Views: 0.5ms | ActiveRecord: 4.5ms) Completed 200 OK in 164ms (Views: 0.5ms | ActiveRecord: 8.3ms) ``` As you can see, speeds are consistent when doing the harder work out of process. I'm not sure the number of sql queries we're saving, but based on the logs alone it's a pretty good amount. @dzaporozhets @yorickpeterse I would love some input on this. See merge request !2631
-rw-r--r--app/controllers/projects/notes_controller.rb2
-rw-r--r--app/services/notes/create_service.rb19
-rw-r--r--app/services/notes/post_process_service.rb30
-rw-r--r--app/workers/new_note_worker.rb12
-rw-r--r--spec/services/notes/create_service_spec.rb4
-rw-r--r--spec/services/notes/post_process_service_spec.rb26
6 files changed, 72 insertions, 21 deletions
diff --git a/app/controllers/projects/notes_controller.rb b/app/controllers/projects/notes_controller.rb
index 4a2599dda37..1b9dd568043 100644
--- a/app/controllers/projects/notes_controller.rb
+++ b/app/controllers/projects/notes_controller.rb
@@ -106,7 +106,7 @@ class Projects::NotesController < Projects::ApplicationController
{ notes_left: [note], notes_right: [] }
else
{ notes_left: [], notes_right: [note] }
- end
+ end
else
template = "projects/notes/_diff_notes_with_reply"
locals = { notes: [note] }
diff --git a/app/services/notes/create_service.rb b/app/services/notes/create_service.rb
index a8486e6a5a1..8d9661167b5 100644
--- a/app/services/notes/create_service.rb
+++ b/app/services/notes/create_service.rb
@@ -6,27 +6,12 @@ module Notes
note.system = false
if note.save
- notification_service.new_note(note)
-
- # Skip system notes, like status changes and cross-references and awards
- unless note.system || note.is_award
- event_service.leave_note(note, note.author)
- note.create_cross_references!
- execute_hooks(note)
- end
+ # Finish the harder work in the background
+ NewNoteWorker.perform_in(2.seconds, note.id, params)
end
note
end
- def hook_data(note)
- Gitlab::NoteDataBuilder.build(note, current_user)
- end
-
- def execute_hooks(note)
- note_data = hook_data(note)
- note.project.execute_hooks(note_data, :note_hooks)
- note.project.execute_services(note_data, :note_hooks)
- end
end
end
diff --git a/app/services/notes/post_process_service.rb b/app/services/notes/post_process_service.rb
new file mode 100644
index 00000000000..f37d3c50cdd
--- /dev/null
+++ b/app/services/notes/post_process_service.rb
@@ -0,0 +1,30 @@
+module Notes
+ class PostProcessService
+
+ attr_accessor :note
+
+ def initialize(note)
+ @note = note
+ end
+
+ def execute
+ # Skip system notes, like status changes and cross-references and awards
+ unless @note.system || @note.is_award
+ EventCreateService.new.leave_note(@note, @note.author)
+ @note.create_cross_references!
+ execute_note_hooks
+ end
+ end
+
+ def hook_data
+ Gitlab::NoteDataBuilder.build(@note, @note.author)
+ end
+
+ def execute_note_hooks
+ note_data = hook_data
+ @note.project.execute_hooks(note_data, :note_hooks)
+ @note.project.execute_services(note_data, :note_hooks)
+ end
+
+ end
+end
diff --git a/app/workers/new_note_worker.rb b/app/workers/new_note_worker.rb
new file mode 100644
index 00000000000..1b3232cd365
--- /dev/null
+++ b/app/workers/new_note_worker.rb
@@ -0,0 +1,12 @@
+class NewNoteWorker
+ include Sidekiq::Worker
+
+ sidekiq_options queue: :default
+
+ def perform(note_id, note_params)
+ note = Note.find(note_id)
+
+ NotificationService.new.new_note(note)
+ Notes::PostProcessService.new(note).execute
+ end
+end
diff --git a/spec/services/notes/create_service_spec.rb b/spec/services/notes/create_service_spec.rb
index a797a2fe4aa..ff23f13e1cb 100644
--- a/spec/services/notes/create_service_spec.rb
+++ b/spec/services/notes/create_service_spec.rb
@@ -14,9 +14,7 @@ describe Notes::CreateService, services: true do
noteable_type: 'Issue',
noteable_id: issue.id
}
-
- expect(project).to receive(:execute_hooks)
- expect(project).to receive(:execute_services)
+
@note = Notes::CreateService.new(project, user, opts).execute
end
diff --git a/spec/services/notes/post_process_service_spec.rb b/spec/services/notes/post_process_service_spec.rb
new file mode 100644
index 00000000000..1a3f339bd64
--- /dev/null
+++ b/spec/services/notes/post_process_service_spec.rb
@@ -0,0 +1,26 @@
+require 'spec_helper'
+
+describe Notes::PostProcessService, services: true do
+ let(:project) { create(:empty_project) }
+ let(:issue) { create(:issue, project: project) }
+ let(:user) { create(:user) }
+
+ describe :execute do
+ before do
+ project.team << [user, :master]
+ note_opts = {
+ note: 'Awesome comment',
+ noteable_type: 'Issue',
+ noteable_id: issue.id
+ }
+
+ @note = Notes::CreateService.new(project, user, note_opts).execute
+ end
+
+ it do
+ expect(project).to receive(:execute_hooks)
+ expect(project).to receive(:execute_services)
+ Notes::PostProcessService.new(@note).execute
+ end
+ end
+end