当我的应用程序获得一些重要负载时,我正在考虑将我的Rails应用程序切换到Sidekiq和Puma。但是,它们要求应用程序是线程安全的。
通常被认为不是线程安全的事情之一是全局变量。但我的应用程序使用Rails应用程序和教程中的常见模式,您可以在初始化程序中定义全局变量,如下所示:
# config/initializers/aws.rb
...
$s3_bucket = Aws::S3::Resource.new.bucket(ENV['AWS_S3_BUCKET'])
# config/initializers/mixpanel.rb
$mixpanel = Mixpanel::Tracker.new(ENV['MIXPANEL_TOKEN']) do |*message|
...
end
# config/initializers/redis.rb
$redis = Redis.new(host: ENV['REDIS_HOST'], port: ENV['REDIS_PORT'])
# config/initializers/twilio.rb
$twilio_client = Twilio::REST::Client.new(ENV['TWILIO_ACCOUNT_SID'], ENV['TWILIO_AUTH_TOKEN'])
我喜欢这种方法,因为代码库的其余部分可以非常轻松地使用这些变量,并且它使它变得更加简洁。
但这些全局变量是否是线程安全的?如果没有,我的选择是什么?我最好使用一种仍然可以使代码库易于阅读的解决方案。
答案 0 :(得分:2)
初始化程序在创建其他线程之前在主线程中运行。它们可能是线程不安全的。
更好的解决方案是在每次使用之前实例化mixpanel / twilio_client / etc,或者使用连接池。