Skip to content
Snippets Groups Projects
Commit dec341ca authored by Douwe Maan's avatar Douwe Maan
Browse files

Merge branch 'improve-project-external-issue-trackers' into 'master'

Greatly improve external_issue_tracker performance

See 3d41133d48f6522b8755bb91b804864e8e520871 for all the details. As an aside, this commit contains a set of migrations that will introduce downtime as they add a column with a default value which in turn locks the entire table (at least on PostgreSQL).

See merge request !2498
parents 425f8d6f b4ee6f57
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -468,12 +468,9 @@ class Project < ActiveRecord::Base
!external_issue_tracker
end
 
def external_issues_trackers
services.select(&:issue_tracker?).reject(&:default?)
end
def external_issue_tracker
@external_issues_tracker ||= external_issues_trackers.find(&:activated?)
@external_issue_tracker ||=
services.issue_trackers.active.without_defaults.first
end
 
def can_have_issues_tracker_id?
Loading
Loading
Loading
Loading
@@ -23,14 +23,12 @@
# List methods you need to implement to get your CI service
# working with GitLab Merge Requests
class CiService < Service
def category
:ci
end
default_value_for :category, 'ci'
def valid_token?(token)
self.respond_to?(:token) && self.token.present? && self.token == token
end
def supported_events
%w(push)
end
Loading
Loading
Loading
Loading
@@ -24,9 +24,7 @@ class GitlabIssueTrackerService < IssueTrackerService
 
prop_accessor :title, :description, :project_url, :issues_url, :new_issue_url
 
def default?
true
end
default_value_for :default, true
 
def to_param
'gitlab'
Loading
Loading
Loading
Loading
@@ -23,12 +23,10 @@ class IssueTrackerService < Service
 
validates :project_url, :issues_url, :new_issue_url, presence: true, if: :activated?
 
def category
:issue_tracker
end
default_value_for :category, 'issue_tracker'
 
def default?
false
default
end
 
def issue_url(iid)
Loading
Loading
Loading
Loading
@@ -43,6 +43,9 @@ class Service < ActiveRecord::Base
validates :project_id, presence: true, unless: Proc.new { |service| service.template? }
 
scope :visible, -> { where.not(type: ['GitlabIssueTrackerService', 'GitlabCiService']) }
scope :issue_trackers, -> { where(category: 'issue_tracker') }
scope :active, -> { where(active: true) }
scope :without_defaults, -> { where(default: false) }
 
scope :push_hooks, -> { where(push_events: true, active: true) }
scope :tag_push_hooks, -> { where(tag_push_events: true, active: true) }
Loading
Loading
@@ -51,6 +54,8 @@ class Service < ActiveRecord::Base
scope :note_hooks, -> { where(note_events: true, active: true) }
scope :build_hooks, -> { where(build_events: true, active: true) }
 
default_value_for :category, 'common'
def activated?
active
end
Loading
Loading
@@ -60,7 +65,7 @@ class Service < ActiveRecord::Base
end
 
def category
:common
read_attribute(:category).to_sym
end
 
def initialize_properties
Loading
Loading
@@ -153,7 +158,7 @@ class Service < ActiveRecord::Base
 
# Returns a hash of the properties that have been assigned a new value since last save,
# indicating their original values (attr => original value).
# ActiveRecord does not provide a mechanism to track changes in serialized keys,
# ActiveRecord does not provide a mechanism to track changes in serialized keys,
# so we need a specific implementation for service properties.
# This allows to track changes to properties set with the accessor methods,
# but not direct manipulation of properties hash.
Loading
Loading
@@ -164,7 +169,7 @@ class Service < ActiveRecord::Base
def reset_updated_properties
@updated_properties = nil
end
def async_execute(data)
return unless supported_events.include?(data[:object_kind])
 
Loading
Loading
class AddServicesCategory < ActiveRecord::Migration
def up
add_column :services, :category, :string, default: 'common', null: false
category = quote_column_name('category')
type = quote_column_name('type')
execute <<-EOF
UPDATE services
SET #{category} = 'issue_tracker'
WHERE #{type} IN (
'CustomIssueTrackerService',
'GitlabIssueTrackerService',
'IssueTrackerService',
'JiraService',
'RedmineService'
);
EOF
execute <<-EOF
UPDATE services
SET #{category} = 'ci'
WHERE #{type} IN (
'BambooService',
'BuildkiteService',
'CiService',
'DroneCiService',
'GitlabCiService',
'TeamcityService'
);
EOF
add_index :services, :category
end
def down
remove_column :services, :category
end
end
class AddServicesDefault < ActiveRecord::Migration
def up
add_column :services, :default, :boolean, default: false
default = quote_column_name('default')
type = quote_column_name('type')
execute <<-EOF
UPDATE services
SET #{default} = true
WHERE #{type} = 'GitlabIssueTrackerService'
EOF
add_index :services, :default
end
def down
remove_column :services, :default
end
end
Loading
Loading
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
 
ActiveRecord::Schema.define(version: 20160113111034) do
ActiveRecord::Schema.define(version: 20160119112418) do
 
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
Loading
Loading
@@ -725,20 +725,24 @@ ActiveRecord::Schema.define(version: 20160113111034) do
t.string "type"
t.string "title"
t.integer "project_id"
t.datetime "created_at"
t.datetime "updated_at"
t.boolean "active", default: false, null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.boolean "active", null: false
t.text "properties"
t.boolean "template", default: false
t.boolean "push_events", default: true
t.boolean "issues_events", default: true
t.boolean "merge_requests_events", default: true
t.boolean "tag_push_events", default: true
t.boolean "note_events", default: true, null: false
t.boolean "build_events", default: false, null: false
end
t.boolean "template", default: false
t.boolean "push_events", default: true
t.boolean "issues_events", default: true
t.boolean "merge_requests_events", default: true
t.boolean "tag_push_events", default: true
t.boolean "note_events", default: true, null: false
t.boolean "build_events", default: false, null: false
t.string "category", default: "common", null: false
t.boolean "default", default: false
end
add_index "services", ["category"], name: "index_services_on_category", using: :btree
add_index "services", ["created_at", "id"], name: "index_services_on_created_at_and_id", using: :btree
add_index "services", ["default"], name: "index_services_on_default", using: :btree
add_index "services", ["project_id"], name: "index_services_on_project_id", using: :btree
add_index "services", ["template"], name: "index_services_on_template", using: :btree
 
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment