Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ThreadError can't create Thread: Resource temporarily unavailable #4353

Closed
dbelloGitHub opened this issue Feb 4, 2021 · 7 comments · Fixed by #4670
Closed

ThreadError can't create Thread: Resource temporarily unavailable #4353

dbelloGitHub opened this issue Feb 4, 2021 · 7 comments · Fixed by #4670

Comments

@dbelloGitHub
Copy link

dbelloGitHub commented Feb 4, 2021

Same problem as Issue 3217 while creating a new site with Jekyll.
To fix, I was intent to clear all Ruby Apps from CPanel and Setup new App from scratch, entering to virtual environment from Terminal

[myuser@host ~]$ source /h/myuser/rubyvenv/rubyApps/2.6/bin/activate
(rubyApps:2.6)[myuser@host rubyApps]$ 

then

$ gem install bundler jekyll

no problem

gem install racc
gem install bootstrap -v 4.6.0
gem install jquery-rails
gem install bootstrap-sass
cd ~/rubyApps

Then, this command not run completely:

jekyll new myproject

nor

jekyll new myproject --force

Then create a site, but with this error:

ThreadError: can't create Thread: Resource temporarily unavailable

--- ERROR REPORT TEMPLATE -------------------------------------------------------

Error Report

Questions

Please fill out answers to these questions, it'll help us figure out
why things are going wrong.

  • What did you do?

I ran the command /h/myuser/rubyvenv/rubyApps/2.6/gems/bundler-2.2.8/exe/bundle install

  • What did you expect to happen?

I expected Bundler to...

  • What happened instead?

Instead, what happened was...

  • Have you tried any solutions posted on similar issues in our issue tracker, stack overflow, or google?

I tried...

...

Backtrace

ThreadError: can't create Thread: Resource temporarily unavailable
/opt/alt/ruby26/lib64/ruby/2.6.0/timeout.rb:83:in `start'
/opt/alt/ruby26/lib64/ruby/2.6.0/timeout.rb:83:in `block in timeout'
/opt/alt/ruby26/lib64/ruby/2.6.0/timeout.rb:103:in `timeout'
/opt/alt/ruby26/lib64/ruby/2.6.0/net/http.rb:945:in `connect'
/opt/alt/ruby26/lib64/ruby/2.6.0/net/http.rb:930:in `do_start'
/opt/alt/ruby26/lib64/ruby/2.6.0/net/http.rb:925:in `start'
/h/myuser/rubyvenv/rubyApps/2.6/gems/bundler-2.2.8/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb:657:in `start'
/h/myuser/rubyvenv/rubyApps/2.6/gems/bundler-2.2.8/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb:597:in `connection_for'
/h/myuser/rubyvenv/rubyApps/2.6/gems/bundler-2.2.8/lib/bundler/vendored_persistent.rb:16:in `connection_for'
/h/myuser/rubyvenv/rubyApps/2.6/gems/bundler-2.2.8/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb:870:in `request'
/h/myuser/rubyvenv/rubyApps/2.6/gems/bundler-2.2.8/lib/bundler/fetcher/downloader.rb:59:in `request'
/h/myuser/rubyvenv/rubyApps/2.6/gems/bundler-2.2.8/lib/bundler/fetcher/downloader.rb:17:in `fetch'
/h/myuser/rubyvenv/rubyApps/2.6/gems/bundler-2.2.8/lib/bundler/fetcher/compact_index.rb:131:in `call'
/h/myuser/rubyvenv/rubyApps/2.6/gems/bundler-2.2.8/lib/bundler/compact_index_client/updater.rb:48:in `block in update'
/h/myuser/rubyvenv/rubyApps/2.6/gems/bundler-2.2.8/lib/bundler/vendor/tmpdir/lib/tmpdir.rb:96:in `mktmpdir'
/h/myuser/rubyvenv/rubyApps/2.6/gems/bundler-2.2.8/lib/bundler/compact_index_client/updater.rb:29:in `update'
/h/myuser/rubyvenv/rubyApps/2.6/gems/bundler-2.2.8/lib/bundler/compact_index_client.rb:98:in `update'
/h/myuser/rubyvenv/rubyApps/2.6/gems/bundler-2.2.8/lib/bundler/compact_index_client.rb:114:in `update_info'
/h/myuser/rubyvenv/rubyApps/2.6/gems/bundler-2.2.8/lib/bundler/compact_index_client.rb:71:in `block in dependencies'
/h/myuser/rubyvenv/rubyApps/2.6/gems/bundler-2.2.8/lib/bundler/fetcher/compact_index.rb:97:in `block (2 levels) in parallel_compact_index_client'
/h/myuser/rubyvenv/rubyApps/2.6/gems/bundler-2.2.8/lib/bundler/worker.rb:62:in `apply_func'
/h/myuser/rubyvenv/rubyApps/2.6/gems/bundler-2.2.8/lib/bundler/worker.rb:57:in `block in process_queue'
/h/myuser/rubyvenv/rubyApps/2.6/gems/bundler-2.2.8/lib/bundler/worker.rb:54:in `loop'
/h/myuser/rubyvenv/rubyApps/2.6/gems/bundler-2.2.8/lib/bundler/worker.rb:54:in `process_queue'
/h/myuser/rubyvenv/rubyApps/2.6/gems/bundler-2.2.8/lib/bundler/worker.rb:88:in `block (2 levels) in create_threads'

Environment

Bundler 2.2.8
Platforms ruby, x86_64-linux
Ruby 2.6.4p104 (2019-08-28 revision 67798) [x86_64-linux]
Full Path /opt/alt/ruby26/bin/ruby
Config Dir /etc
RubyGems 3.0.3
Gem Home /h/myuser/rubyvenv/rubyApps/2.6
Gem Path /h/myuser/rubyvenv/rubyApps/2.6:/opt/alt/ruby26/lib64/ruby/gems/2.6.0
User Home /h/myuser
User Path /h/myuser/.gem/ruby/2.6.0
Bin Dir /h/myuser/rubyvenv/rubyApps/2.6/bin
OpenSSL
Compiled OpenSSL 1.0.2k 26 Jan 2017
Loaded OpenSSL 1.0.2k-fips 26 Jan 2017
Cert File /etc/pki/tls/cert.pem
Cert Dir /etc/pki/tls/certs
Tools
Git 2.28.0
RVM not installed
rbenv not installed
chruby not installed

Bundler Build Metadata

Built At 2021-02-02
Git SHA 4015e550dc
Released Version true

Gemfile

Gemfile

source "https://rubygems.org"
# Hello! This is where you manage which Jekyll version is used to run.
# When you want to use a different version, change it below, save the
# file and run `bundle install`. Run Jekyll with `bundle exec`, like so:
#
# bundle exec jekyll serve
#
# This will help ensure the proper Jekyll version is running.
# Happy Jekylling!
gem "jekyll", "~> 4.2.0"
# This is the default theme for new Jekyll sites. You may change this to anything you like.
gem "minima", "~> 2.5"
# If you want to use GitHub Pages, remove the "gem "jekyll"" above and
# uncomment the line below. To upgrade, run `bundle update github-pages`.
# gem "github-pages", group: :jekyll_plugins
# If you have any plugins, put them here!
group :jekyll_plugins do
gem "jekyll-feed", "~> 0.12"
end

# Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem
# and associated library.
platforms :mingw, :x64_mingw, :mswin, :jruby do
gem "tzinfo", "~> 1.2"
gem "tzinfo-data"
end

# Performance-booster for watching directories on Windows
gem "wdm", "~> 0.1.1", :platforms => [:mingw, :x64_mingw, :mswin]

Gemfile.lock

<No /h/myuser/rubyApps/slides/Gemfile.lock found>

--- TEMPLATE END ----------------------------------------------------------------

@deivid-rodriguez
Copy link
Member

Could you remove all Bundler: prefixes so that the markdown of our bug report template renders fine? Thanks!

@duckinator
Copy link
Member

I went ahead and removed the Bundler: prefixes and wrapped a few things in code blocks for y'all so the issue is a bit easier to read. 🙂

@duckinator
Copy link
Member

duckinator commented Feb 10, 2021

It looks like, as in #3217, the problem is that the thread pool is still hard-coded to 25 threads.

PR rubygems/bundler#6617 was opened to resolve it, but not merged with the following reasoning:

We have a particular way handling configuration that uses ENV vars, see bundle config. And i don't believe this is the appropriate fix either. The issue with the linked ticket is that there is a bug in the compact index that is preventing it from handling the case of not having enough threads available. This will have to be fixed.

When Bundler was merged into the RubyGems repository, that became PR #3434, but it was never updated to address the original problem brought up by @colby-swandale.

I'm not sure how to fix it in a better way than the original PR proposed, aside from using the more typical Bundler-y way to handle environment variables. It seems like the thread pool is preventing Bundler from being able to create more threads later, and I'm not sure that's a problem we can predict. It might make sense to just let users override it and inform them of how.

@deivid-rodriguez
Copy link
Member

I don't think an ENV variable is an appropriate fix either. Users would have to know that they need to tweak this environment variable when this error happens, and that's quite unlikely to happen.

From reading rubygems/bundler#4367, I understand to this error can be raised by ruby when lacking memory or exhausting resource limits. Since this can always potentially happen, I guess we need to handle the error gracefully and stop creating more threads.

@dbelloGitHub
Copy link
Author

I apologize for the late reply and consequently not cleaning up the bug report.
My Hosting provider was responsible for the event by limiting the number of processes in shared hosting. So the failure results every time the maximum number of processes is reached among all users.

@duckinator
Copy link
Member

duckinator commented Feb 14, 2021

@dbelloGitHub thank you for the extra information.

Looking at rubygems/bundler#4367, the original commenter and a few other people confirmed this exists on shared hosting. It looks like at this point 6 people have confirmed it exists on multiple shared hosting providers.


I dug into the code involved in the backtraces people have provided, and found a complication with trying to handle the error gracefully. Sometimes the problem originates from Bundler directly spawning a new thread. But in other instances, like the backtrace @dbelloGitHub provided above, Bundler may already done spawning all of its threads. The problem in this case was caused by Net::HTTP#connect using Timeout.timeout, which spawns a thread itself.

And by that point, we've spawned all of the Bundler threads. So we'd have to clean up the entire Worker object and try again with a smaller number.


Net::HTTP#connect uses Timeout.timeout which spawns its own thread, and this means Bundler is spawning at least twice(!) as many threads as the number in the Bundler::Worker call implies!

The number of workers (for everything except Rubinius) is 25, and there is the parent process, so there is 51 threads minimum when using bundle install! And that's assuming no other parts of the codebase directly or indirectly spawn any threads.

@deivid-rodriguez
Copy link
Member

Thanks for looking into that @duckinator. Hopefully the extra thread in net/http will go away with ruby/net-http#10.

In any case, this seems like unnecessarily high number to me. We could run some performance tests with gemfiles of different sizes over a cold compact index cache to make sure the performance doesn't regress, and reduce this number. We could, for example, make it match Bundler.settings[:jobs].

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants