Search code examples
ruby-on-railsrubypuma

How to get isolated thread information from Puma


I have a Rails application using Puma.

The Puma configuration is:

workers 2
threads 1, 16
app_dir = File.expand_path("../..", __FILE__)
tmp_dir = "#{app_dir}/tmp"
rails_env = ENV['RAILS_ENV'] || "development"
environment rails_env
daemonize
bind "unix://#{tmp_dir}/sockets/puma.sock"
stdout_redirect "log/puma.stdout.log", "log/puma.stderr.log", true
pidfile "#{tmp_dir}/pids/puma.pid"
state_path "#{tmp_dir}/pids/puma.state"

When two requests have one pid, they have a common state.

For example, we have a simple singleton:

class Test
  include Singleton
  attr_accessor :field
end

The first request sets:

Test.instance.field = 'from_first_request'

In the second request we see:

puts(Test.instance.field) # => 'from_first_request'

Is this the correct behaviour? Can we get the isolated state for any requests on one pid?


Solution

  • If you use Rails 5.0 you can also use new thread specific variable, like this:

    class SomeSingleton
      thread_mattr_accessor :field
    end
    

    If your Rails version < 5.0 you're still able to store field in Thread.current, like this:

    class SomeSingleton
      def self.field=(field)
        Thread.current[:field] = field
      end
    
      def self.field
        Thread.current[:field]
      end
    end
    

    Let me know if it helped.