discourse/lib/site_icon_manager.rb
Alan Guo Xiang Tan 8cfe203383 PERF: Defer setting of distributed cache in performance critical paths.
Setting a key/value pair in DistributedCache involves waiting on the
write to Redis to finish. In most cases, we don't need to wait on the
setting of the cache to finish. We just need to take our return value
and move on.
2021-06-03 09:30:52 +08:00

81 lines
2.5 KiB
Ruby

# frozen_string_literal: true
module SiteIconManager
extend GlobalPath
@cache = DistributedCache.new('icon_manager')
SKETCH_LOGO_ID = -6
ICONS = {
digest_logo: { width: nil, height: nil, settings: [:digest_logo, :logo], fallback_to_sketch: false, resize_required: false },
mobile_logo: { width: nil, height: nil, settings: [:mobile_logo, :logo], fallback_to_sketch: false, resize_required: false },
large_icon: { width: nil, height: nil, settings: [:large_icon, :logo_small], fallback_to_sketch: true, resize_required: false },
manifest_icon: { width: 512, height: 512, settings: [:manifest_icon, :large_icon, :logo_small], fallback_to_sketch: true, resize_required: true },
favicon: { width: 32, height: 32, settings: [:favicon, :large_icon, :logo_small], fallback_to_sketch: true, resize_required: false },
apple_touch_icon: { width: 180, height: 180, settings: [:apple_touch_icon, :large_icon, :logo_small], fallback_to_sketch: true, resize_required: false },
opengraph_image: { width: nil, height: nil, settings: [:opengraph_image, :large_icon, :logo_small, :logo], fallback_to_sketch: true, resize_required: false },
}
WATCHED_SETTINGS = ICONS.keys + [:logo, :logo_small]
def self.ensure_optimized!
unless @disabled
ICONS.each do |name, info|
icon = resolve_original(info)
if info[:height] && info[:width]
OptimizedImage.create_for(icon, info[:width], info[:height])
end
end
end
@cache.clear
end
ICONS.each do |name, info|
define_singleton_method(name) do
icon = resolve_original(info)
if info[:height] && info[:width]
result = OptimizedImage.find_by(upload: icon, height: info[:height], width: info[:width])
end
result = icon if !result && !info[:resize_required]
result
end
define_singleton_method("#{name}_url") do
get_set_cache("#{name}_url") do
icon = self.public_send(name)
icon ? full_cdn_url(icon.url) : ''
end
end
end
# Used in test mode
def self.disable
@disabled = true
end
def self.enable
@disabled = false
end
private
def self.get_set_cache(key)
return @cache[key] if @cache[key]
value = yield
@cache.defer_set(key, value)
value
end
def self.resolve_original(info)
info[:settings].each do |setting_name|
value = SiteSetting.get(setting_name)
return value if value
end
return Upload.find(SKETCH_LOGO_ID) if info[:fallback_to_sketch]
nil
end
end