Skip to content

Compatibility with puma and Rails - "WARNING: Detected 2 Thread(s) started in app boot:" #868

@ndbroadbent

Description

@ndbroadbent
* Operating system:                mac + linux
* Ruby implementation:             Ruby
* `concurrent-ruby` version:       1.1.6
* `concurrent-ruby-ext` installed: no
* `concurrent-ruby-edge` used: no

Hello, I'm trying to debug a thread warning in puma. Here's the issue I opened over there: puma/puma#2237

The problem seems to be that requiring lib/concurrent-ruby/concurrent/atomic/ruby_thread_local_var.rb immediately starts a new Thread.

Here's the stack trace when puma loads my application:

/Users/myuser/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/concurrent-ruby-1.1.6/lib/concurrent-ruby/concurrent/atomic/ruby_thread_local_var.rb:8:in `<module:Concurrent>'
/Users/myuser/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/concurrent-ruby-1.1.6/lib/concurrent-ruby/concurrent/atomic/ruby_thread_local_var.rb:4:in `<top (required)>'
/Users/myuser/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/concurrent-ruby-1.1.6/lib/concurrent-ruby/concurrent/atomic/thread_local_var.rb:2:in `require'
/Users/myuser/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/concurrent-ruby-1.1.6/lib/concurrent-ruby/concurrent/atomic/thread_local_var.rb:2:in `<top (required)>'
/Users/myuser/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/concurrent-ruby-1.1.6/lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb:5:in `require'
/Users/myuser/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/concurrent-ruby-1.1.6/lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb:5:in `<top (required)>'
/Users/myuser/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/concurrent-ruby-1.1.6/lib/concurrent-ruby/concurrent/atomics.rb:8:in `require'
/Users/myuser/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/concurrent-ruby-1.1.6/lib/concurrent-ruby/concurrent/atomics.rb:8:in `<top (required)>'
/Users/myuser/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/concurrent-ruby-1.1.6/lib/concurrent-ruby/concurrent.rb:6:in `require'
/Users/myuser/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/concurrent-ruby-1.1.6/lib/concurrent-ruby/concurrent.rb:6:in `<top (required)>'
/Users/myuser/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/activesupport-5.2.4.2/lib/active_support/logger_silence.rb:5:in `require'
/Users/myuser/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/activesupport-5.2.4.2/lib/active_support/logger_silence.rb:5:in `<top (required)>'
/Users/myuser/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/activesupport-5.2.4.2/lib/active_support/logger.rb:3:in `require'
/Users/myuser/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/activesupport-5.2.4.2/lib/active_support/logger.rb:3:in `<top (required)>'
/Users/myuser/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/activesupport-5.2.4.2/lib/active_support.rb:29:in `require'
/Users/myuser/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/activesupport-5.2.4.2/lib/active_support.rb:29:in `<top (required)>'
/Users/myuser/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/railties-5.2.4.2/lib/rails.rb:7:in `require'
/Users/myuser/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/railties-5.2.4.2/lib/rails.rb:7:in `<top (required)>'
/Users/myuser/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/railties-5.2.4.2/lib/rails/all.rb:3:in `require'
/Users/myuser/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/railties-5.2.4.2/lib/rails/all.rb:3:in `<top (required)>'
/Users/myuser/code/myapp/config/application.rb:7:in `require'
/Users/myuser/code/myapp/config/application.rb:7:in `<top (required)>'
/Users/myuser/code/myapp/config/environment.rb:4:in `require_relative'
/Users/myuser/code/myapp/config/environment.rb:4:in `<top (required)>'
config.ru:5:in `require_relative'
config.ru:5:in `block in <main>'
/Users/myuser/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/rack-2.2.2/lib/rack/builder.rb:116:in `eval'
/Users/myuser/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/rack-2.2.2/lib/rack/builder.rb:116:in `new_from_string'
/Users/myuser/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/rack-2.2.2/lib/rack/builder.rb:105:in `load_file'
/Users/myuser/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/rack-2.2.2/lib/rack/builder.rb:66:in `parse_file'
/Users/myuser/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/puma-4.3.3/lib/puma/configuration.rb:321:in `load_rackup'
/Users/myuser/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/puma-4.3.3/lib/puma/configuration.rb:246:in `app'
/Users/myuser/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/puma-4.3.3/lib/puma/runner.rb:155:in `load_and_bind'
/Users/myuser/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/puma-4.3.3/lib/puma/cluster.rb:413:in `run'
/Users/myuser/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/puma-4.3.3/lib/puma/launcher.rb:172:in `run'
/Users/myuser/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/puma-4.3.3/lib/puma/cli.rb:80:in `run'
/Users/myuser/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/puma-4.3.3/bin/puma:10:in `<top (required)>'
/Users/myuser/.rbenv/versions/2.6.5/bin/puma:23:in `load'
/Users/myuser/.rbenv/versions/2.6.5/bin/puma:23:in `<main>'

When puma is running in "clustered" mode, it forks a new process for each worker, so the Thread started by the RubyThreadLocalVar class is not running inside any of these worker processes. Is this a problem? My first impression is that this might cause a memory leak because none of the thread-local variables are ever getting released and garbage collected in my puma workers. (But I'm not sure which parts of Rails are using this.)

New threads can be started inside puma.on_worker_boot, so should we doing something like:

puma.on_worker_boot do
  Concurrent::RubyThreadLocalVar.start_thread!
end

Or maybe puma should do this automatically if it detects the concurrent-ruby library?

Thanks for your time!

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugA bug in the library or documentation.high-priorityShould be done ASAP.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions