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.
This commit is contained in:
Alan Guo Xiang Tan 2021-06-02 15:46:48 +08:00
parent 83211cff25
commit 8cfe203383
5 changed files with 25 additions and 9 deletions

View File

@ -155,10 +155,10 @@ class Theme < ActiveRecord::Base
end end
def self.get_set_cache(key, &blk) def self.get_set_cache(key, &blk)
if @cache.hash.key? key.to_s return @cache[key] if @cache[key]
return @cache[key] value = blk.call
end @cache.defer_set(key, value)
@cache[key] = blk.call value
end end
def self.theme_ids def self.theme_ids

View File

@ -11,4 +11,12 @@ class DistributedCache < MessageBus::DistributedCache
app_version: Discourse.git_version app_version: Discourse.git_version
) )
end end
# Defer setting of the key in the cache for performance critical path to avoid
# waiting on MessageBus to publish the message which involves writing to Redis.
def defer_set(k, v)
Scheduler::Defer.later("#{@key}_set") do
self[k] = v
end
end
end end

View File

@ -62,7 +62,10 @@ module SiteIconManager
private private
def self.get_set_cache(key) def self.get_set_cache(key)
@cache[key] ||= yield return @cache[key] if @cache[key]
value = yield
@cache.defer_set(key, value)
value
end end
def self.resolve_original(info) def self.resolve_original(info)

View File

@ -88,14 +88,16 @@ class Stylesheet::Manager
builder.compile unless File.exists?(builder.stylesheet_fullpath) builder.compile unless File.exists?(builder.stylesheet_fullpath)
href = builder.stylesheet_path(current_hostname) href = builder.stylesheet_path(current_hostname)
end end
cache[cache_key] = href
cache.defer_set(cache_key, href)
end end
data[:theme_id] = theme_id if theme_id.present? && data[:theme_id].blank? data[:theme_id] = theme_id if theme_id.present? && data[:theme_id].blank?
data[:new_href] = href data[:new_href] = href
stylesheets << data stylesheets << data
end end
cache[array_cache_key] = stylesheets.freeze
cache.defer_set(array_cache_key, stylesheets.freeze)
stylesheets stylesheets
end end
end end
@ -128,7 +130,7 @@ class Stylesheet::Manager
href = builder.stylesheet_path(current_hostname) href = builder.stylesheet_path(current_hostname)
stylesheet[:new_href] = href stylesheet[:new_href] = href
cache[cache_key] = stylesheet.freeze cache.defer_set(cache_key, stylesheet.freeze)
stylesheet stylesheet
end end

View File

@ -478,7 +478,10 @@ License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL
end end
def self.get_set_cache(key) def self.get_set_cache(key)
cache[key] ||= yield return cache[key] if cache[key]
value = yield
cache.defer_set(key, value)
value
end end
def self.cache def self.cache