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
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitlab/pages/cache_control.rb')
-rw-r--r--lib/gitlab/pages/cache_control.rb66
1 files changed, 52 insertions, 14 deletions
diff --git a/lib/gitlab/pages/cache_control.rb b/lib/gitlab/pages/cache_control.rb
index 187d5f907e4..be39e52b342 100644
--- a/lib/gitlab/pages/cache_control.rb
+++ b/lib/gitlab/pages/cache_control.rb
@@ -1,5 +1,7 @@
# frozen_string_literal: true
+require 'set'
+
module Gitlab
module Pages
class CacheControl
@@ -9,7 +11,9 @@ module Gitlab
# To avoid delivering expired deployment URL in the cached payload,
# use a longer expiration time in the deployment URL
DEPLOYMENT_EXPIRATION = (EXPIRE + 12.hours)
- CACHE_KEY_FORMAT = 'pages_domain_for_%{type}_%{id}_%{settings}'
+
+ SETTINGS_CACHE_KEY = 'pages_domain_for_%{type}_%{id}'
+ PAYLOAD_CACHE_KEY = '%{settings_cache_key}_%{settings_hash}'
class << self
def for_project(project_id)
@@ -29,29 +33,63 @@ module Gitlab
end
def cache_key
- strong_memoize(:cache_key) do
- CACHE_KEY_FORMAT % {
- type: @type,
- id: @id,
- settings: settings
- }
+ strong_memoize(:payload_cache_key) do
+ cache_settings_hash!
+
+ payload_cache_key_for(settings_hash)
end
end
+ # Invalidates the cache.
+ #
+ # Since rails nodes and sidekiq nodes have different application settings,
+ # and the invalidation happens in a sidekiq node, we have to use the
+ # cached settings hash to build the payload cache key to be invalidated.
def clear_cache
- Rails.cache.delete(cache_key)
+ keys = cached_settings_hashes
+ .map { |hash| payload_cache_key_for(hash) }
+ .push(settings_cache_key)
+
+ Rails.cache.delete_multi(keys)
end
private
- def settings
- values = ::Gitlab.config.pages.dup
+ # Since rails nodes and sidekiq nodes have different application settings,
+ # we cache the application settings hash when creating the payload cache
+ # so we can use these values to invalidate the cache in a sidekiq node later.
+ def cache_settings_hash!
+ cached = cached_settings_hashes.to_set
+ Rails.cache.write(settings_cache_key, cached.add(settings_hash))
+ end
+
+ def cached_settings_hashes
+ Rails.cache.read(settings_cache_key) || []
+ end
+
+ def payload_cache_key_for(settings_hash)
+ PAYLOAD_CACHE_KEY % {
+ settings_cache_key: settings_cache_key,
+ settings_hash: settings_hash
+ }
+ end
- values['app_settings'] = ::Gitlab::CurrentSettings.attributes.slice(
- 'force_pages_access_control'
- )
+ def settings_cache_key
+ strong_memoize(:settings_cache_key) do
+ SETTINGS_CACHE_KEY % { type: @type, id: @id }
+ end
+ end
- ::Digest::SHA256.hexdigest(values.inspect)
+ def settings_hash
+ strong_memoize(:settings_hash) do
+ values = ::Gitlab.config.pages.dup
+
+ values['app_settings'] = ::Gitlab::CurrentSettings.attributes.slice(
+ 'force_pages_access_control'
+ )
+
+ ::Digest::SHA256.hexdigest(values.inspect)
+ end
end
end
end