Commit 6ecf16b8 authored by James Lopez's avatar James Lopez

refactor code based on feedback

parent ce418036
...@@ -16,7 +16,7 @@ class Admin::ServicesController < Admin::ApplicationController ...@@ -16,7 +16,7 @@ class Admin::ServicesController < Admin::ApplicationController
def update def update
if service.update_attributes(service_params[:service]) if service.update_attributes(service_params[:service])
PropagateProjectServiceWorker.perform_async(service.id) if service.active? PropagateServiceTemplateWorker.perform_async(service.id) if service.active?
redirect_to admin_application_settings_services_path, redirect_to admin_application_settings_services_path,
notice: 'Application settings saved successfully' notice: 'Application settings saved successfully'
......
module Projects module Projects
class PropagateService class PropagateServiceTemplate
BATCH_SIZE = 100 BATCH_SIZE = 100
def self.propagate(*args) def self.propagate(*args)
...@@ -36,9 +36,7 @@ module Projects ...@@ -36,9 +36,7 @@ module Projects
end end
Project.transaction do Project.transaction do
Gitlab::SQL::BulkInsert.new(service_hash.keys + ['project_id'], bulk_insert_services(service_hash.keys + ['project_id'], service_list)
service_list,
'services').execute
run_callbacks(batch) run_callbacks(batch)
end end
end end
...@@ -54,11 +52,22 @@ module Projects ...@@ -54,11 +52,22 @@ module Projects
WHERE services.project_id = projects.id WHERE services.project_id = projects.id
AND services.type = '#{@template.type}' AND services.type = '#{@template.type}'
) )
AND projects.pending_delete = false
AND projects.archived = false
LIMIT #{BATCH_SIZE} LIMIT #{BATCH_SIZE}
SQL SQL
) )
end end
def bulk_insert_services(columns, values_array)
ActiveRecord::Base.connection.execute(
<<-SQL.strip_heredoc
INSERT INTO services (#{columns.join(', ')})
VALUES #{values_array.map { |tuple| "(#{tuple.join(', ')})" }.join(', ')}
SQL
)
end
def service_hash def service_hash
@service_hash ||= @service_hash ||=
begin begin
...@@ -84,11 +93,11 @@ module Projects ...@@ -84,11 +93,11 @@ module Projects
end end
def active_external_issue_tracker? def active_external_issue_tracker?
@template['category'] == 'issue_tracker' && @template['active'] && !@template['default'] @template.category == :issue_tracker && !@template.default
end end
def active_external_wiki? def active_external_wiki?
@template['type'] == 'ExternalWikiService' && @template['active'] @template.type == 'ExternalWikiService'
end end
end end
end end
# Worker for updating any project specific caches. # Worker for updating any project specific caches.
class PropagateProjectServiceWorker class PropagateServiceTemplateWorker
include Sidekiq::Worker include Sidekiq::Worker
include DedicatedSidekiqQueue include DedicatedSidekiqQueue
...@@ -10,14 +10,14 @@ class PropagateProjectServiceWorker ...@@ -10,14 +10,14 @@ class PropagateProjectServiceWorker
def perform(template_id) def perform(template_id)
return unless try_obtain_lease_for(template_id) return unless try_obtain_lease_for(template_id)
Projects::PropagateService.propagate(Service.find_by(id: template_id)) Projects::PropagateServiceTemplate.propagate(Service.find_by(id: template_id))
end end
private private
def try_obtain_lease_for(template_id) def try_obtain_lease_for(template_id)
Gitlab::ExclusiveLease. Gitlab::ExclusiveLease.
new("propagate_project_service_worker:#{template_id}", timeout: LEASE_TIMEOUT). new("propagate_service_template_worker:#{template_id}", timeout: LEASE_TIMEOUT).
try_obtain try_obtain
end end
end end
...@@ -53,4 +53,4 @@ ...@@ -53,4 +53,4 @@
- [pages, 1] - [pages, 1]
- [system_hook_push, 1] - [system_hook_push, 1]
- [update_user_activity, 1] - [update_user_activity, 1]
- [propagate_project_service, 1] - [propagate_service_template, 1]
module Gitlab
module SQL
# Class for building SQL bulk inserts
class BulkInsert
def initialize(columns, values_array, table)
@columns = columns
@values_array = values_array
@table = table
end
def execute
ActiveRecord::Base.connection.execute(
<<-SQL.strip_heredoc
INSERT INTO #{@table} (#{@columns.join(', ')})
VALUES #{@values_array.map { |tuple| "(#{tuple.join(', ')})" }.join(', ')}
SQL
)
end
end
end
end
...@@ -39,16 +39,16 @@ describe Admin::ServicesController do ...@@ -39,16 +39,16 @@ describe Admin::ServicesController do
) )
end end
it 'updates the service params successfully and calls the propagation worker' do it 'calls the propagation worker when service is active' do
expect(PropagateProjectServiceWorker).to receive(:perform_async).with(service.id) expect(PropagateServiceTemplateWorker).to receive(:perform_async).with(service.id)
put :update, id: service.id, service: { active: true } put :update, id: service.id, service: { active: true }
expect(response).to have_http_status(302) expect(response).to have_http_status(302)
end end
it 'updates the service params successfully' do it 'does not call the propagation worker when service is not active' do
expect(PropagateProjectServiceWorker).not_to receive(:perform_async) expect(PropagateServiceTemplateWorker).not_to receive(:perform_async)
put :update, id: service.id, service: { properties: {} } put :update, id: service.id, service: { properties: {} }
......
require 'spec_helper' require 'spec_helper'
describe Projects::PropagateService, services: true do describe Projects::PropagateServiceTemplate, services: true do
describe '.propagate!' do describe '.propagate' do
let!(:service_template) do let!(:service_template) do
PushoverService.create( PushoverService.create(
template: true, template: true,
...@@ -23,9 +23,10 @@ describe Projects::PropagateService, services: true do ...@@ -23,9 +23,10 @@ describe Projects::PropagateService, services: true do
end end
it 'creates services for a project that has another service' do it 'creates services for a project that has another service' do
other_service = BambooService.create( BambooService.create(
template: true, template: true,
active: true, active: true,
project: project,
properties: { properties: {
bamboo_url: 'http://gitlab.com', bamboo_url: 'http://gitlab.com',
username: 'mic', username: 'mic',
...@@ -34,8 +35,6 @@ describe Projects::PropagateService, services: true do ...@@ -34,8 +35,6 @@ describe Projects::PropagateService, services: true do
} }
) )
Service.build_from_template(project.id, other_service).save!
expect { described_class.propagate(service_template) }. expect { described_class.propagate(service_template) }.
to change { Service.count }.by(1) to change { Service.count }.by(1)
end end
...@@ -62,7 +61,7 @@ describe Projects::PropagateService, services: true do ...@@ -62,7 +61,7 @@ describe Projects::PropagateService, services: true do
it 'creates the service containing the template attributes' do it 'creates the service containing the template attributes' do
described_class.propagate(service_template) described_class.propagate(service_template)
service = Service.find_by(type: service_template.type, template: false) service = Service.find_by!(type: service_template.type, template: false)
expect(service.properties).to eq(service_template.properties) expect(service.properties).to eq(service_template.properties)
end end
...@@ -70,7 +69,7 @@ describe Projects::PropagateService, services: true do ...@@ -70,7 +69,7 @@ describe Projects::PropagateService, services: true do
describe 'bulk update' do describe 'bulk update' do
it 'creates services for all projects' do it 'creates services for all projects' do
project_total = 5 project_total = 5
stub_const 'Projects::PropagateService::BATCH_SIZE', 3 stub_const 'Projects::PropagateServiceTemplate::BATCH_SIZE', 3
project_total.times { create(:empty_project) } project_total.times { create(:empty_project) }
...@@ -81,7 +80,7 @@ describe Projects::PropagateService, services: true do ...@@ -81,7 +80,7 @@ describe Projects::PropagateService, services: true do
describe 'external tracker' do describe 'external tracker' do
it 'updates the project external tracker' do it 'updates the project external tracker' do
service_template.update(category: 'issue_tracker', default: false) service_template.update!(category: 'issue_tracker', default: false)
expect { described_class.propagate(service_template) }. expect { described_class.propagate(service_template) }.
to change { project.reload.has_external_issue_tracker }.to(true) to change { project.reload.has_external_issue_tracker }.to(true)
...@@ -90,7 +89,7 @@ describe Projects::PropagateService, services: true do ...@@ -90,7 +89,7 @@ describe Projects::PropagateService, services: true do
describe 'external wiki' do describe 'external wiki' do
it 'updates the project external tracker' do it 'updates the project external tracker' do
service_template.update(type: 'ExternalWikiService') service_template.update!(type: 'ExternalWikiService')
expect { described_class.propagate(service_template) }. expect { described_class.propagate(service_template) }.
to change { project.reload.has_external_wiki }.to(true) to change { project.reload.has_external_wiki }.to(true)
......
require 'spec_helper' require 'spec_helper'
describe PropagateProjectServiceWorker do describe PropagateServiceTemplateWorker do
let!(:service_template) do let!(:service_template) do
PushoverService.create( PushoverService.create(
template: true, template: true,
...@@ -21,7 +21,7 @@ describe PropagateProjectServiceWorker do ...@@ -21,7 +21,7 @@ describe PropagateProjectServiceWorker do
describe '#perform' do describe '#perform' do
it 'calls the propagate service with the template' do it 'calls the propagate service with the template' do
expect(Projects::PropagateService).to receive(:propagate).with(service_template) expect(Projects::PropagateServiceTemplate).to receive(:propagate).with(service_template)
subject.perform(service_template.id) subject.perform(service_template.id)
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