diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-06-07 21:10:23 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-06-07 21:10:23 +0300 |
commit | 21e144f387bc4d77f6128ee87549daf174467518 (patch) | |
tree | a1f7ca7673e157e9175b527fc435b480c974645a /lib | |
parent | 79f98200f84590af39cf1af7f57f6e8ba89d2bb6 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'lib')
-rw-r--r-- | lib/api/entities/basic_project_details.rb | 25 | ||||
-rw-r--r-- | lib/gitlab/database/postgresql_adapter/type_map_cache.rb | 44 | ||||
-rw-r--r-- | lib/gitlab/json.rb | 4 |
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 |