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...

Другие вопросы по тегам