diff options
author | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2016-01-29 13:51:34 +0000 |
---|---|---|
committer | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2016-01-29 13:51:34 +0000 |
commit | 227728712ec5b469a36dbaf8c9511098b4817741 (patch) | |
tree | e443174f1322c3970fbd1f67b7b18ec95ef1fe44 | |
parent | e221990ebac72b8b229b8c3ff38069edbf7776a7 (diff) | |
parent | f3d4f2eac7bcf787a00a6cff694fbfa8969830f4 (diff) | |
download | gitlab-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.rb | 2 | ||||
-rw-r--r-- | app/services/notes/create_service.rb | 19 | ||||
-rw-r--r-- | app/services/notes/post_process_service.rb | 30 | ||||
-rw-r--r-- | app/workers/new_note_worker.rb | 12 | ||||
-rw-r--r-- | spec/services/notes/create_service_spec.rb | 4 | ||||
-rw-r--r-- | spec/services/notes/post_process_service_spec.rb | 26 |
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 |