Module: API::Helpers::Caching
Constant Summary collapse
- DEFAULT_CACHE_OPTIONS =
{ race_condition_ttl: 5.seconds, version: 1 }.freeze
- PAGINATION_HEADERS =
%w[X-Per-Page X-Page X-Next-Page X-Prev-Page Link X-Total X-Total-Pages].freeze
Constants included from Gitlab::Cache::Helpers
Gitlab::Cache::Helpers::DEFAULT_EXPIRY
Instance Method Summary collapse
-
#cache_action(key, **custom_cache_opts) ⇒ Gitlab::Json::PrecompiledJson
Action caching implementation.
-
#cache_action_if(conditional, *opts, **kwargs) ⇒ Object
Conditionally cache an action.
-
#cache_action_unless(conditional, *opts, **kwargs) ⇒ Object
Conditionally cache an action.
-
#present_cached(obj_or_collection, with:, cache_context: -> (_) { current_user&.cache_key }, expires_in: Gitlab::Cache::Helpers::DEFAULT_EXPIRY, **presenter_args) ⇒ Gitlab::Json::PrecompiledJson
This is functionally equivalent to the standard ‘#present` used in Grape endpoints, but the JSON for the object, or for each object of a collection, will be cached.
Methods included from Gitlab::Cache::Helpers
Instance Method Details
#cache_action(key, **custom_cache_opts) ⇒ Gitlab::Json::PrecompiledJson
Action caching implementation
This allows you to wrap an entire API endpoint call in a cache, useful for short TTL caches to effectively rate-limit an endpoint. The block will be converted to JSON and cached, and returns a ‘Gitlab::Json::PrecompiledJson` object which will be exported without secondary conversion.
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/api/helpers/caching.rb', line 79 def cache_action(key, **custom_cache_opts) cache_opts = (custom_cache_opts) json, cached_headers = cache.fetch(key, **cache_opts) do response = yield cached_body = response.is_a?(Gitlab::Json::PrecompiledJson) ? response.to_s : Gitlab::Json.dump(response.as_json) cached_headers = header.slice(*PAGINATION_HEADERS) [cached_body, cached_headers] end cached_headers.each do |key, value| next if header.key?(key) header key, value end body Gitlab::Json::PrecompiledJson.new(json) end |
#cache_action_if(conditional, *opts, **kwargs) ⇒ Object
Conditionally cache an action
Perform a ‘cache_action` only if the conditional passes
103 104 105 106 107 108 109 110 111 |
# File 'lib/api/helpers/caching.rb', line 103 def cache_action_if(conditional, *opts, **kwargs) if conditional cache_action(*opts, **kwargs) do yield end else yield end end |
#cache_action_unless(conditional, *opts, **kwargs) ⇒ Object
Conditionally cache an action
Perform a ‘cache_action` unless the conditional passes
116 117 118 119 120 |
# File 'lib/api/helpers/caching.rb', line 116 def cache_action_unless(conditional, *opts, **kwargs) cache_action_if(!conditional, *opts, **kwargs) do yield end end |
#present_cached(obj_or_collection, with:, cache_context: -> (_) { current_user&.cache_key }, expires_in: Gitlab::Cache::Helpers::DEFAULT_EXPIRY, **presenter_args) ⇒ Gitlab::Json::PrecompiledJson
This is functionally equivalent to the standard ‘#present` used in Grape endpoints, but the JSON for the object, or for each object of a collection, will be cached.
With a collection all the keys will be fetched in a single call and the Entity rendered for those missing from the cache, which are then written back into it.
Both the single object, and all objects inside a collection, must respond to ‘#cache_key`.
To override the Grape formatter we return a custom wrapper in ‘Gitlab::Json::PrecompiledJson` which tells the `Gitlab::Json::GrapeFormatter` to export the string without conversion.
A cache context can be supplied to add more context to the cache key. This defaults to including the ‘current_user` in every key for safety, unless overridden.
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/api/helpers/caching.rb', line 45 def present_cached(obj_or_collection, with:, cache_context: -> (_) { current_user&.cache_key }, expires_in: Gitlab::Cache::Helpers::DEFAULT_EXPIRY, **presenter_args) json = if obj_or_collection.is_a?(Enumerable) cached_collection( obj_or_collection, presenter: with, presenter_args: presenter_args, context: cache_context, expires_in: expires_in ) else cached_object( obj_or_collection, presenter: with, presenter_args: presenter_args, context: cache_context, expires_in: expires_in ) end body Gitlab::Json::PrecompiledJson.new(json) end |