Rails 中类变量的线程安全 - 这可行吗?
我正在多租户 (SaaS) Rails 应用程序中使用 Ruby Money gem,并且正在寻找将 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”一。
顺便说一句,这里是 Money 类中的相关 default_currency
代码:
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
那么,这在多用户设置中会按预期工作吗?我还需要做什么吗?
I'm using the Ruby Money gem in a multi-tenant (SaaS) Rails app, and am looking for a good way to make the Money.default_currency
be set to an Account's preference for each request. I have several currency-related models in the app that use the Money class.
I have everything working properly in development, but I'm just looking for some feedback on whether or not the solution with have repercussions in production.
Here's what I did in my ApplicationController (irrelevant code removed for brevity):
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
So the code above will set the default_currency
class variable to the current account's preference, or default back to 'USD' if there isn't one.
By the way, here's the relevant default_currency
code in the Money class:
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
So, will this work as expected in a multi-user setting? Anything else I need to do?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
大多数 Rails 应用程序都不以多线程模式运行 - 给定实例一次仅处理一个请求(这是默认设置)。
如果您的应用处于多线程模式,这将是危险的 -
Money.default_currency
可能会在请求中途被刚刚传入的新请求更改。如果您确实想让该线程安全,您可以可以使用 Thread.current 哈希来获得每个线程的 default_currency 值Most rails apps don't run in multithreaded mode - a given instance is only ever handling one request at a time (this is the default).
If your app was in multithreaded mode this would be dangerous -
Money.default_currency
could get changed halfway through a request by the new request that has just come in. If you did want to make this thread safe, you could use theThread.current
hash to have per thread values ofdefault_currency