PERF: bypass slow locale lookups in various cases
Previously as soon as any override was defined we would regress to the slow path for locale lookups. Additionally if `raise: true` was specified which rails likes to add in views we would bypass the cache The new design manages to use the fast path for many more cases
This commit is contained in:
parent
78509eacb7
commit
6d8eb9c144
|
@ -19,7 +19,7 @@ module I18n
|
|||
alias_method :reload_no_cache!, :reload!
|
||||
alias_method :locale_no_cache=, :locale=
|
||||
|
||||
LRU_CACHE_SIZE = 300
|
||||
LRU_CACHE_SIZE = 400
|
||||
|
||||
def init_accelerator!
|
||||
@overrides_enabled = true
|
||||
|
@ -43,7 +43,8 @@ module I18n
|
|||
# load plural rules from plugins
|
||||
DiscoursePluginRegistry.locales.each do |plugin_locale, options|
|
||||
if options[:plural]
|
||||
I18n.backend.store_translations(plugin_locale,
|
||||
I18n.backend.store_translations(
|
||||
plugin_locale,
|
||||
i18n: { plural: options[:plural] }
|
||||
)
|
||||
end
|
||||
|
@ -94,18 +95,43 @@ module I18n
|
|||
@overrides_enabled = true
|
||||
end
|
||||
|
||||
def translate_no_override(*args)
|
||||
return translate_no_cache(*args) if args.length > 1 && args[1].present?
|
||||
class MissingTranslation; end
|
||||
|
||||
options = args.last.is_a?(Hash) ? args.pop.dup : {}
|
||||
key = args.shift
|
||||
locale = options[:locale] || config.locale
|
||||
def translate_no_override(key, options)
|
||||
# note we skip cache for :format and :count
|
||||
should_raise = false
|
||||
locale = nil
|
||||
|
||||
dup_options = nil
|
||||
if options
|
||||
dup_options = options.dup
|
||||
should_raise = dup_options.delete(:raise)
|
||||
locale = dup_options.delete(:locale)
|
||||
end
|
||||
|
||||
if dup_options.present?
|
||||
return translate_no_cache(key, options)
|
||||
end
|
||||
|
||||
locale ||= config.locale
|
||||
|
||||
@cache ||= LruRedux::ThreadSafeCache.new(LRU_CACHE_SIZE)
|
||||
k = "#{key}#{locale}#{config.backend.object_id}"
|
||||
|
||||
@cache.getset(k) do
|
||||
translate_no_cache(key, options).freeze
|
||||
val = @cache.getset(k) do
|
||||
begin
|
||||
translate_no_cache(key, raise: true).freeze
|
||||
rescue I18n::MissingTranslationData
|
||||
MissingTranslation
|
||||
end
|
||||
end
|
||||
|
||||
if val != MissingTranslation
|
||||
val
|
||||
elsif should_raise
|
||||
raise I18n::MissingTranslationData.new(locale, key)
|
||||
else
|
||||
-"translation missing: #{locale}.#{key}"
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -153,11 +179,16 @@ module I18n
|
|||
if @overrides_enabled
|
||||
overrides = {}
|
||||
|
||||
# for now lets do all the expensive work for keys with count
|
||||
# no choice really
|
||||
has_override = !!options[:count]
|
||||
|
||||
I18n.fallbacks[locale].each do |l|
|
||||
overrides[l] = overrides_by_locale(l)
|
||||
override = overrides[l] = overrides_by_locale(l)
|
||||
has_override ||= override.key?(key)
|
||||
end
|
||||
|
||||
if overrides.present?
|
||||
if has_override && overrides.present?
|
||||
if options.present?
|
||||
options[:overrides] = overrides
|
||||
|
||||
|
|
|
@ -24,6 +24,15 @@ describe "translate accelerator" do
|
|||
expect(override.persisted?).to eq(true)
|
||||
end
|
||||
|
||||
it "supports raising if requested, and cache bypasses" do
|
||||
expect { I18n.t('i_am_an_unknown_key99', raise: true) }.to raise_error(I18n::MissingTranslationData)
|
||||
|
||||
orig = I18n.t('i_am_an_unknown_key99')
|
||||
|
||||
expect(I18n.t('i_am_an_unknown_key99').object_id).to eq(orig.object_id)
|
||||
expect(I18n.t('i_am_an_unknown_key99')).to eq("translation missing: en_US.i_am_an_unknown_key99")
|
||||
end
|
||||
|
||||
it "overrides for both string and symbol keys" do
|
||||
key = 'user.email.not_allowed'
|
||||
text_overriden = 'foobar'
|
||||
|
@ -124,6 +133,7 @@ describe "translate accelerator" do
|
|||
I18n.overrides_disabled do
|
||||
expect(I18n.t('title')).to eq(orig_title)
|
||||
end
|
||||
|
||||
expect(I18n.t('title')).to eq('overridden title')
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue