I18n.with_locale потокобезопасен?
Я создал функцию публикации новостей на языке создателя страницы.
Вот код, который создает новости:
def add_news
locale = creator.language.blank? ? I18n.locale : creator.language
I18n.with_locale(locale) do
title = I18n.t('news.subject')
end
create_news({title: title})
end
Работает хорошо, новости создаются на хорошем языке. Но иногда используется неправильный язык. Я прочитал исходный код i18n ( https://github.com/svenfuchs/i18n/blob/master/lib/i18n.rb), и для меня функция with_local не является поточно-ориентированной. Я был очень удивлен, потому что я не прочитал ни одного поста по этой проблеме.
Так что ты думаешь об этом? Threadsafe или нет? Знаете ли вы другое решение, если так?
Спасибо и бр,
Эрик
1 ответ
Похоже, это из руководств по Ruby on Rails, так как он использует Thread.current.
Также проведен небольшой (неоспоримый) эксперимент:
n = I18n.available_locales.length
10.times do |i|
loc = I18n.available_locales[i % n]
Thread.new do
I18n.with_locale(loc) do
puts "#{loc} #{I18n.t 'one.of.your.keys'}"
end
end
end
Thread.current
не является потокобезопасным для потоковых веб-серверов, таких как Puma или Thin. См. https://github.com/steveklabnik/request_store для более подробного объяснения:
Эта проблема
В наши дни все беспокоятся о параллелизме. Поэтому люди используют эти причудливые многопоточные веб-серверы, такие как Thin или Puma. Но если вы используете Thread.current и используете один из этих серверов, будьте осторожны! Значения могут сохраняться дольше, чем вы ожидаете, и это может вызвать ошибки. Например, если бы у нас было это в нашем контроллере:
def index
Thread.current[:counter] ||= 0
Thread.current[:counter] += 1
render :text => Thread.current[:counter]
end
Если бы мы запустили это на МРТ с Webrick, вы бы каждый раз получали 1 в качестве вывода. Но если вы запустите его с Thin, вы получите 1, затем 2, затем 3...