f14647fdae
Previously `ProjectCacheWorker` would be scheduled once per ref, which would generate unnecessary I/O and load on Sidekiq, especially if many tags or branches were pushed at once. `ProjectCacheWorker` would expire three items: 1. Repository size: This only needs to be updated once per push. 2. Commit count: This only needs to be updated if the default branch is updated. 3. Project method caches: This only needs to be updated if the default branch changes, but only if certain files change (e.g. README, CHANGELOG, etc.). Because the third item requires looking at the actual changes in the commit deltas, we schedule one `ProjectCacheWorker` to handle the first two cases, and schedule a separate `ProjectCacheWorker` for the third case if it is needed. As a result, this brings down the number of `ProjectCacheWorker` jobs from N to 2. Closes https://gitlab.com/gitlab-org/gitlab-ce/issues/52046
70 lines
1.8 KiB
Ruby
70 lines
1.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Gitlab
|
|
class GitPostReceive
|
|
include Gitlab::Identifier
|
|
attr_reader :project, :identifier, :changes, :push_options
|
|
|
|
def initialize(project, identifier, changes, push_options = {})
|
|
@project = project
|
|
@identifier = identifier
|
|
@changes = deserialize_changes(changes)
|
|
@push_options = push_options
|
|
end
|
|
|
|
def identify
|
|
super(identifier)
|
|
end
|
|
|
|
def changes_refs
|
|
return changes unless block_given?
|
|
|
|
changes.each do |change|
|
|
change.strip!
|
|
oldrev, newrev, ref = change.split(' ')
|
|
|
|
yield oldrev, newrev, ref
|
|
end
|
|
end
|
|
|
|
def includes_branches?
|
|
enum_for(:changes_refs).any? do |_oldrev, _newrev, ref|
|
|
Gitlab::Git.branch_ref?(ref)
|
|
end
|
|
end
|
|
|
|
def includes_tags?
|
|
enum_for(:changes_refs).any? do |_oldrev, _newrev, ref|
|
|
Gitlab::Git.tag_ref?(ref)
|
|
end
|
|
end
|
|
|
|
def includes_default_branch?
|
|
# If the branch doesn't have a default branch yet, we presume the
|
|
# first branch pushed will be the default.
|
|
return true unless project.default_branch.present?
|
|
|
|
enum_for(:changes_refs).any? do |_oldrev, _newrev, ref|
|
|
Gitlab::Git.branch_ref?(ref) &&
|
|
Gitlab::Git.branch_name(ref) == project.default_branch
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def deserialize_changes(changes)
|
|
utf8_encode_changes(changes).each_line
|
|
end
|
|
|
|
def utf8_encode_changes(changes)
|
|
changes.force_encoding('UTF-8')
|
|
return changes if changes.valid_encoding?
|
|
|
|
# Convert non-UTF-8 branch/tag names to UTF-8 so they can be dumped as JSON.
|
|
detection = CharlockHolmes::EncodingDetector.detect(changes)
|
|
return changes unless detection && detection[:encoding]
|
|
|
|
CharlockHolmes::Converter.convert(changes, detection[:encoding], 'UTF-8')
|
|
end
|
|
end
|
|
end
|