Browse Source

Add cache buster feature for media files (#15155)

Nginx can be configured to bypass proxy cache when a special header
is in the request. If the response is cacheable, it will replace
the cache for that request. Proxy caching of media files is
desirable when using object storage as a way of minimizing bandwidth
costs, but has the drawback of leaving deleted media files for
a configured amount of cache time. A cache buster can make those
media files immediately unavailable. This especially makes sense
when suspending and unsuspending an account.
master
Eugen Rochko 4 years ago
committed by GitHub
parent
commit
df1653174b
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 60 additions and 1 deletions
  1. +28
    -0
      app/lib/cache_buster.rb
  2. +2
    -0
      app/services/suspend_account_service.rb
  3. +2
    -0
      app/services/unsuspend_account_service.rb
  4. +18
    -0
      app/workers/cache_buster_worker.rb
  5. +10
    -0
      config/initializers/cache_buster.rb
  6. +0
    -1
      config/initializers/paperclip.rb

+ 28
- 0
app/lib/cache_buster.rb View File

@ -0,0 +1,28 @@
# frozen_string_literal: true
class CacheBuster
def initialize(options = {})
@secret_header = options[:secret_header] || 'Secret-Header'
@secret = options[:secret] || 'True'
end
def bust(url)
site = Addressable::URI.parse(url).normalized_site
request_pool.with(site) do |http_client|
build_request(url, http_client).perform
end
end
private
def request_pool
RequestPool.current
end
def build_request(url, http_client)
Request.new(:get, url, http_client: http_client).tap do |request|
request.add_headers(@secret_header => @secret)
end
end
end

+ 2
- 0
app/services/suspend_account_service.rb View File

@ -78,6 +78,8 @@ class SuspendAccountService < BaseService
Rails.logger.warn "Tried to change permission on non-existent file #{attachment.path(style)}"
end
end
CacheBusterWorker.perform_async(attachment.path(style)) if Rails.configuration.x.cache_buster_enabled
end
end
end

+ 2
- 0
app/services/unsuspend_account_service.rb View File

@ -69,6 +69,8 @@ class UnsuspendAccountService < BaseService
Rails.logger.warn "Tried to change permission on non-existent file #{attachment.path(style)}"
end
end
CacheBusterWorker.perform_async(attachment.path(style)) if Rails.configuration.x.cache_buster_enabled
end
end
end

+ 18
- 0
app/workers/cache_buster_worker.rb View File

@ -0,0 +1,18 @@
# frozen_string_literal: true
class CacheBusterWorker
include Sidekiq::Worker
include RoutingHelper
sidekiq_options queue: 'pull'
def perform(path)
cache_buster.bust(full_asset_url(path))
end
private
def cache_buster
CacheBuster.new(Rails.configuration.x.cache_buster)
end
end

+ 10
- 0
config/initializers/cache_buster.rb View File

@ -0,0 +1,10 @@
# frozen_string_literal: true
Rails.application.configure do
config.x.cache_buster_enabled = ENV['CACHE_BUSTER_ENABLED'] == 'true'
config.x.cache_buster = {
secret_header: ENV['CACHE_BUSTER_SECRET_HEADER'],
secret: ENV['CACHE_BUSTER_SECRET'],
}
end

+ 0
- 1
config/initializers/paperclip.rb View File

@ -107,7 +107,6 @@ elsif ENV['SWIFT_ENABLED'] == 'true'
else
Paperclip::Attachment.default_options.merge!(
storage: :filesystem,
use_timestamp: true,
path: File.join(ENV.fetch('PAPERCLIP_ROOT_PATH', File.join(':rails_root', 'public', 'system')), ':prefix_path:class', ':attachment', ':id_partition', ':style', ':filename'),
url: ENV.fetch('PAPERCLIP_ROOT_URL', '/system') + '/:prefix_url:class/:attachment/:id_partition/:style/:filename',
)

Loading…
Cancel
Save