debian-mirror-gitlab/lib/gitlab/pages/cache_control.rb

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

97 lines
2.7 KiB
Ruby
Raw Normal View History

2022-08-13 15:12:31 +05:30
# frozen_string_literal: true
2023-03-04 22:38:38 +05:30
require 'set'
2022-08-13 15:12:31 +05:30
module Gitlab
module Pages
class CacheControl
2022-11-25 23:54:43 +05:30
include Gitlab::Utils::StrongMemoize
2022-08-13 15:12:31 +05:30
2022-11-25 23:54:43 +05:30
EXPIRE = 12.hours
# To avoid delivering expired deployment URL in the cached payload,
# use a longer expiration time in the deployment URL
DEPLOYMENT_EXPIRATION = (EXPIRE + 12.hours)
2023-03-04 22:38:38 +05:30
SETTINGS_CACHE_KEY = 'pages_domain_for_%{type}_%{id}'
PAYLOAD_CACHE_KEY = '%{settings_cache_key}_%{settings_hash}'
2022-08-13 15:12:31 +05:30
class << self
def for_project(project_id)
new(type: :project, id: project_id)
end
def for_namespace(namespace_id)
new(type: :namespace, id: namespace_id)
end
end
def initialize(type:, id:)
raise(ArgumentError, "type must be :namespace or :project") unless %i[namespace project].include?(type)
2022-11-25 23:54:43 +05:30
@type = type
@id = id
end
def cache_key
2023-03-04 22:38:38 +05:30
strong_memoize(:payload_cache_key) do
cache_settings_hash!
payload_cache_key_for(settings_hash)
2022-11-25 23:54:43 +05:30
end
2022-08-13 15:12:31 +05:30
end
2023-03-04 22:38:38 +05:30
# 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.
2022-08-13 15:12:31 +05:30
def clear_cache
2023-03-04 22:38:38 +05:30
keys = cached_settings_hashes
.map { |hash| payload_cache_key_for(hash) }
.push(settings_cache_key)
Rails.cache.delete_multi(keys)
2022-08-13 15:12:31 +05:30
end
2022-11-25 23:54:43 +05:30
private
2023-03-04 22:38:38 +05:30
# 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
2022-11-25 23:54:43 +05:30
2023-03-04 22:38:38 +05:30
def settings_cache_key
strong_memoize(:settings_cache_key) do
SETTINGS_CACHE_KEY % { type: @type, id: @id }
end
end
2022-11-25 23:54:43 +05:30
2023-03-04 22:38:38 +05:30
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
2022-11-25 23:54:43 +05:30
end
2022-08-13 15:12:31 +05:30
end
end
end