简体   繁体   English

如何拥有线程安全的Rails初始化器?

[英]How to have thread-safe Rails initializers?

I am thinking about switching my Rails app to Sidekiq and Puma when my app gets some significant load. 我正在考虑将我的Rails应用程序转移到Sidekiq和Puma时,我的应用程序会承受大量负载。 However, they require the app to be thread-safe. 但是,它们要求应用程序是线程安全的。

One of the things that are typically considered not thread-safe are global variables. 全局变量通常被认为不是线程安全的事情之一。 But my app uses a common pattern found in Rails apps and tutorials, where you define global variables in initializers like so: 但是我的应用程序使用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'])

I like this approach because the rest of the codebase can use these variables very easily, and it makes it is terser. 我喜欢这种方法,因为代码库的其余部分可以非常轻松地使用这些变量,这使它变得更简单。

But are these global variables thread-safe? 但是这些全局变量是线程安全的吗? If not, what are my options? 如果没有,我有什么选择? I would preferably use a solution that still keeps the codebase easy to read. 我最好使用仍然使代码库易于阅读的解决方案。

Initializers are run in the main thread before other threads are created. 在创建其他线程之前,初始化程序在主线程中运行。 They can be thread-unsafe. 它们可能是线程不安全的。

A better solution would be to either instantiate mixpanel/twilio_client/etc every time before using them, or use a connection pool. 更好的解决方案是在每次使用它们之前实例化mixpanel / twilio_client / etc或使用连接池。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM