Потоковая безопасность переменной класса в Rails - будет ли это работать? - PullRequest
4 голосов
/ 31 января 2012

Я использую Ruby Money gem в мультитенантном (SaaS) приложении Rails и ищу хороший способ настроить Money.default_currency на настройку учетной записи для каждого запроса , У меня есть несколько валютных моделей в приложении, которые используют класс Money.

У меня все работает должным образом в разработке, но я просто хочу получить отзывы о том, будут ли решения с производственными последствиями.

Вот что я сделал в моем ApplicationController (нерелевантный код удален для краткости):

class ApplicationController < ActionController::Base
  before_filter :set_currency

  private

  def set_currency
    Money.default_currency = Money::Currency.new(current_account.present? && current_account.currency.present? ?
                                                 current_account.currency : 'USD')
  end
end

Таким образом, приведенный выше код установит переменную класса default_currency в соответствии с предпочтением текущей учетной записи или по умолчанию вернет значение «USD», если его нет.

Кстати, вот соответствующий код default_currency в классе Money:

class Money

  # Class Methods
  class << self

    # The default currency, which is used when +Money.new+ is called without an
    # explicit currency argument. The default value is Currency.new("USD"). The
    # value must be a valid +Money::Currency+ instance.
    #
    # @return [Money::Currency]
    attr_accessor :default_currency

  end
end

Итак, будет ли это работать должным образом в многопользовательском режиме? Что-нибудь еще, что мне нужно сделать?

1 Ответ

2 голосов
/ 31 января 2012

Большинство приложений rails не работают в многопоточном режиме - данный экземпляр обрабатывает только один запрос за раз (это значение по умолчанию).

Если ваше приложение находилось в многопоточном режиме, это было бы опасно- Money.default_currency может быть изменено на полпути через запрос от только что поступившего нового запроса. Если вы действительно хотите сделать этот поток безопасным, вы можете использовать хеш Thread.current, чтобы значения для каждого потока составляли default_currency

...