Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-06-07 21:10:23 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-06-07 21:10:23 +0300
commit21e144f387bc4d77f6128ee87549daf174467518 (patch)
treea1f7ca7673e157e9175b527fc435b480c974645a /lib
parent79f98200f84590af39cf1af7f57f6e8ba89d2bb6 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'lib')
-rw-r--r--lib/api/entities/basic_project_details.rb25
-rw-r--r--lib/gitlab/database/postgresql_adapter/type_map_cache.rb44
-rw-r--r--lib/gitlab/json.rb4
3 files changed, 64 insertions, 9 deletions
diff --git a/lib/api/entities/basic_project_details.rb b/lib/api/entities/basic_project_details.rb
index 2de49d6ed40..91831fe2bdf 100644
--- a/lib/api/entities/basic_project_details.rb
+++ b/lib/api/entities/basic_project_details.rb
@@ -4,15 +4,13 @@ module API
module Entities
class BasicProjectDetails < Entities::ProjectIdentity
include ::API::ProjectsRelationBuilder
+ include Gitlab::Utils::StrongMemoize
expose :default_branch, if: -> (project, options) { Ability.allowed?(options[:current_user], :download_code, project) }
# Avoids an N+1 query: https://github.com/mbleigh/acts-as-taggable-on/issues/91#issuecomment-168273770
- expose :tag_list do |project|
- # Tags is a preloaded association. If we perform then sorting
- # through the database, it will trigger a new query, ending up
- # in an N+1 if we have several projects
- project.tags.pluck(:name).sort # rubocop:disable CodeReuse/ActiveRecord
- end
+
+ expose :topic_names, as: :tag_list
+ expose :topic_names, as: :topics
expose :ssh_url_to_repo, :http_url_to_repo, :web_url, :readme_url
@@ -40,7 +38,7 @@ module API
# rubocop: disable CodeReuse/ActiveRecord
def self.preload_relation(projects_relation, options = {})
- # Preloading tags, should be done with using only `:tags`,
+ # Preloading topics, should be done with using only `:tags`,
# as `:tags` are defined as: `has_many :tags, through: :taggings`
# N+1 is solved then by using `subject.tags.map(&:name)`
# MR describing the solution: https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/20555
@@ -50,6 +48,19 @@ module API
.preload(namespace: [:route, :owner])
end
# rubocop: enable CodeReuse/ActiveRecord
+
+ private
+
+ alias_method :project, :object
+
+ def topic_names
+ # Topics is a preloaded association. If we perform then sorting
+ # through the database, it will trigger a new query, ending up
+ # in an N+1 if we have several projects
+ strong_memoize(:topic_names) do
+ project.tags.pluck(:name).sort # rubocop:disable CodeReuse/ActiveRecord
+ end
+ end
end
end
end
diff --git a/lib/gitlab/database/postgresql_adapter/type_map_cache.rb b/lib/gitlab/database/postgresql_adapter/type_map_cache.rb
new file mode 100644
index 00000000000..ff66d9115ab
--- /dev/null
+++ b/lib/gitlab/database/postgresql_adapter/type_map_cache.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+# Caches loading of additional types from the DB
+# https://github.com/rails/rails/blob/v6.0.3.2/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L521-L589
+
+# rubocop:disable Gitlab/ModuleWithInstanceVariables
+
+module Gitlab
+ module Database
+ module PostgresqlAdapter
+ module TypeMapCache
+ extend ActiveSupport::Concern
+
+ TYPE_MAP_CACHE_MONITOR = ::Monitor.new
+
+ class_methods do
+ def type_map_cache
+ TYPE_MAP_CACHE_MONITOR.synchronize do
+ @type_map_cache ||= {}
+ end
+ end
+ end
+
+ def initialize_type_map(map = type_map)
+ TYPE_MAP_CACHE_MONITOR.synchronize do
+ cached_type_map = self.class.type_map_cache[@connection_parameters.hash]
+ break @type_map = cached_type_map if cached_type_map
+
+ super
+ self.class.type_map_cache[@connection_parameters.hash] = map
+ end
+ end
+
+ def reload_type_map
+ TYPE_MAP_CACHE_MONITOR.synchronize do
+ self.class.type_map_cache[@connection_parameters.hash] = nil
+ end
+
+ super
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/json.rb b/lib/gitlab/json.rb
index 561cd4509b1..767ce310b5a 100644
--- a/lib/gitlab/json.rb
+++ b/lib/gitlab/json.rb
@@ -242,7 +242,7 @@ module Gitlab
def self.encode(object, limit: 25.megabytes)
return ::Gitlab::Json.dump(object) unless Feature.enabled?(:json_limited_encoder)
- buffer = []
+ buffer = StringIO.new
buffer_size = 0
::Yajl::Encoder.encode(object) do |data_chunk|
@@ -254,7 +254,7 @@ module Gitlab
buffer_size += chunk_size
end
- buffer.join('')
+ buffer.string
end
end
end