I18n.with_locale 线程安全吗?

Is I18n.with_locale threadsafe?

我创建了一个功能,可以使用页面创建者的语言发布新闻。

这是创建新闻的代码:

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 函数不是线程安全的。我很惊讶,因为我没有读过 post 关于那个问题。

那么,你怎么看?线程安全与否?如果是这样,您知道其他解决方案吗?

谢谢你,

埃里克

看起来它来自 Ruby on Rails guides,因为它正在使用 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 这样的线程 Web 服务器来说不是线程安全的。更详细的解释见github.com/steveklabnik/request_store

The problem

Everyone's worrying about concurrency these days. So people are using those fancy threaded web servers, like Thin or Puma. But if you use Thread.current, and you use one of those servers, watch out! Values can stick around longer than you'd expect, and this can cause bugs. For example, if we had this in our controller:

  def index   
    Thread.current[:counter] ||= 0   
    Thread.current[:counter] += 1
    render :text => Thread.current[:counter]
  end

If we ran this on MRI with Webrick, you'd get 1 as output, every time. But if you run it with Thin, you get 1, then 2, then 3...