diff options
Diffstat (limited to 'lib/api')
| -rw-r--r-- | lib/api/helpers/caching.rb | 7 | ||||
| -rw-r--r-- | lib/api/helpers/headers_helpers.rb | 2 | ||||
| -rw-r--r-- | lib/api/internal/base.rb | 2 | ||||
| -rw-r--r-- | lib/api/releases.rb | 16 |
4 files changed, 22 insertions, 5 deletions
diff --git a/lib/api/helpers/caching.rb b/lib/api/helpers/caching.rb index d0f22109879..64b681633b6 100644 --- a/lib/api/helpers/caching.rb +++ b/lib/api/helpers/caching.rb @@ -119,8 +119,11 @@ module API objs.flatten! map = multi_key_map(objs, context: context) - cache.fetch_multi(*map.keys, **kwargs) do |key| - yield map[key] + # TODO: `contextual_cache_key` should be constructed based on the guideline https://docs.gitlab.com/ee/development/redis.html#multi-key-commands. + Gitlab::Instrumentation::RedisClusterValidator.allow_cross_slot_commands do + cache.fetch_multi(*map.keys, **kwargs) do |key| + yield map[key] + end end end diff --git a/lib/api/helpers/headers_helpers.rb b/lib/api/helpers/headers_helpers.rb index 908c57bb04e..56445ccbd0d 100644 --- a/lib/api/helpers/headers_helpers.rb +++ b/lib/api/helpers/headers_helpers.rb @@ -8,7 +8,7 @@ module API def set_http_headers(header_data) header_data.each do |key, value| if value.is_a?(Enumerable) - raise ArgumentError.new("Header value should be a string") + raise ArgumentError, "Header value should be a string" end header "X-Gitlab-#{key.to_s.split('_').collect(&:capitalize).join('-')}", value.to_s diff --git a/lib/api/internal/base.rb b/lib/api/internal/base.rb index 4dcfc0cf7eb..ec69e1da961 100644 --- a/lib/api/internal/base.rb +++ b/lib/api/internal/base.rb @@ -158,7 +158,7 @@ module API status 200 unless actor.key_or_user - raise ActiveRecord::RecordNotFound.new('User not found!') + raise ActiveRecord::RecordNotFound, 'User not found!' end actor.update_last_used_at! diff --git a/lib/api/releases.rb b/lib/api/releases.rb index 0fdbe8ff866..cefdf40d789 100644 --- a/lib/api/releases.rb +++ b/lib/api/releases.rb @@ -33,7 +33,21 @@ module API get ':id/releases' do releases = ::ReleasesFinder.new(user_project, current_user, declared_params.slice(:order_by, :sort)).execute - present paginate(releases), with: Entities::Release, current_user: current_user + if Feature.enabled?(:api_caching_releases, user_project, default_enabled: :yaml) + # We cache the serialized payload per user in order to avoid repeated renderings. + # Since the cached result could contain sensitive information, + # it will expire in a short interval. + present_cached paginate(releases), + with: Entities::Release, + # `current_user` could be absent if the releases are publicly accesible. + # We should not use `cache_key` for the user because the version/updated_at + # context is unnecessary here. + cache_context: -> (_) { "user:{#{current_user&.id}}" }, + expires_in: 5.minutes, + current_user: current_user + else + present paginate(releases), with: Entities::Release, current_user: current_user + end end desc 'Get a single project release' do |
