rails / spring

Rails application preloader
MIT License
2.81k stars 341 forks source link

Spring 4.2.0 crashing when running rake #716

Open fschwahn opened 7 months ago

fschwahn commented 7 months ago

This happened to me when running rails db:migrate.

I have never seen this before, and I have been using spring daily for years. Maybe it is connected to the changes in 4.2.0 (namely #708).

I'm running spring server as a separate process, so I have logs / stacktrace to share:

15:50:59 spring.1 | [2024-04-26 15:50:59 +0200] [4120] [server] accepted client
15:50:59 spring.1 | [2024-04-26 15:50:59 +0200] [4120] [server] running command rake
15:50:59 spring.1 | [2024-04-26 15:50:59 +0200] [4120] [server] shutting down
15:50:59 spring.1 | [2024-04-26 15:50:59 +0200] [4120] [application_manager:development] stopping
15:50:59 spring.1 | [2024-04-26 15:50:59 +0200] [4120] [application_manager:test] stopping
15:50:59 spring.1 | [2024-04-26 15:50:59 +0200] [12426] [application:development] forced exit
15:50:59 spring.1 | /Users/fabian/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/gems/spring-4.2.0/lib/spring/application_manager.rb:63:in `send_io': Invalid argument - sendmsg(2) (Errno::EINVAL)
15:50:59 spring.1 |     from /Users/fabian/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/gems/spring-4.2.0/lib/spring/application_manager.rb:63:in `block in run'
15:50:59 spring.1 |     from /Users/fabian/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/gems/spring-4.2.0/lib/spring/application_manager.rb:44:in `block in with_child'
15:50:59 spring.1 |     from /Users/fabian/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/gems/spring-4.2.0/lib/spring/application_manager.rb:22:in `synchronize'
15:50:59 spring.1 |     from /Users/fabian/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/gems/spring-4.2.0/lib/spring/application_manager.rb:41:in `with_child'
15:50:59 spring.1 |     from /Users/fabian/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/gems/spring-4.2.0/lib/spring/application_manager.rb:62:in `run'
15:50:59 spring.1 |     from /Users/fabian/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/gems/spring-4.2.0/lib/spring/server.rb:70:in `serve'
15:50:59 spring.1 |     from /Users/fabian/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/gems/spring-4.2.0/lib/spring/server.rb:51:in `block in start_server'
15:50:59 spring.1 |     from <internal:kernel>:187:in `loop'
15:50:59 spring.1 |     from /Users/fabian/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/gems/spring-4.2.0/lib/spring/server.rb:51:in `start_server'
15:50:59 spring.1 |     from /Users/fabian/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/gems/spring-4.2.0/lib/spring/server.rb:45:in `boot'
15:50:59 spring.1 |     from /Users/fabian/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/gems/spring-4.2.0/lib/spring/server.rb:14:in `boot'
15:50:59 spring.1 |     from /Users/fabian/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/gems/spring-4.2.0/lib/spring/client/server.rb:10:in `call'
15:50:59 spring.1 |     from /Users/fabian/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/gems/spring-4.2.0/lib/spring/client/command.rb:7:in `call'
15:50:59 spring.1 |     from /Users/fabian/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/gems/spring-4.2.0/lib/spring/client.rb:30:in `run'
15:50:59 spring.1 |     from /Users/fabian/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/gems/spring-4.2.0/bin/spring:49:in `<top (required)>'
15:50:59 spring.1 |     from /Users/fabian/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/gems/spring-4.2.0/lib/spring/binstub.rb:5:in `load'
15:50:59 spring.1 |     from /Users/fabian/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/gems/spring-4.2.0/lib/spring/binstub.rb:5:in `<top (required)>'
15:50:59 spring.1 |     from <internal:/Users/fabian/.rbenv/versions/3.3.1/lib/ruby/3.3.0/rubygems/core_ext/kernel_require.rb>:136:in `require'
15:50:59 spring.1 |     from <internal:/Users/fabian/.rbenv/versions/3.3.1/lib/ruby/3.3.0/rubygems/core_ext/kernel_require.rb>:136:in `require'
15:50:59 spring.1 |     from bin/spring:12:in `block in <main>'
15:50:59 spring.1 |     from <internal:kernel>:90:in `tap'
15:50:59 spring.1 |     from bin/spring:9:in `<main>'
fmichaut-diff commented 4 months ago

Also running into this issue on MacOS.

This happens to me when the spring server is running, but a change gets detected by the watchers (eg: changing a config/ file).

The next client to connect to the server will trigger that error, killing the server process and any live pre-existing client and will make the new client hang indefinitely on preload_status = application.gets.

This is very frustrating when working on a git project, cause every change of branch is likely to trigger a watcher, which breaks the spring server and kills any open session (eg: a rails console being used, open a new terminal to run a rails db:migrate, rails g migration, or even another rails c will kill the running console, and the new process will hang indefinitely and won't even respond to CTRL-C)

I've been running into that issue for months now, it would be great if it could get fixed.

Relates to https://github.com/rails/spring/issues/396, https://github.com/rails/spring/issues/663, looks like this issue is very resilient

prognostikos commented 2 months ago

@fschwahn @fmichaut-diff I have a fix/workaround for this in #727

You could try it out to see if it fixes your issue, I have done so by using bundle open and applied the patch in the pr, as spring doesn't support being run as gem "spring", git: "..."

Would love to hear if it works with your version of rails, ruby, os, etc.

prognostikos commented 2 months ago

Or as noted in CONTRIBUTING.md you can use rake install to test the change.

fschwahn commented 2 months ago

I was able to reproduce reliably using your steps, and after applying your patch it no longer happens. I will now run this patch locally.

prognostikos commented 2 months ago

I was able to reproduce reliably using your steps, and after applying your patch it no longer happens. I will now run this patch locally.

Thanks @fschwahn. If you have a moment to list the versions of your OS, ruby and rails that would be helpful. I'm interested to know if the fix works for more than just for my versions.

fschwahn commented 2 months ago

OS: macOS 14.6.1 Ruby: 3.3.5 Rails: 7.1.3.4

fmichaut-diff commented 2 months ago

I have been testing since yesterday, and things are looking good so far ! Thanks

OS: MacOS 14.6.1 Ruby: 3.3.0 Rails: 7.2.1

chaadow commented 1 week ago

@fschwahn @fmichaut-diff I have a fix/workaround for this in #727

You could try it out to see if it fixes your issue, I have done so by using bundle open and applied the patch in the pr, as spring doesn't support being run as gem "spring", git: "..."

Would love to hear if it works with your version of rails, ruby, os, etc.

I actually managed to make spring work with gem 'spring', github: '...'. I also stumbled onto this in the README, but told myself that this piece of information might be obsolete and was written probably in the 2013/2014 era.

so here is how my bin/spring file look like in my rails project

#!/usr/bin/env ruby

# This file loads Spring without loading other gems in the Gemfile in order to be fast.
# It gets overwritten when you run the `spring binstub` command.

if !defined?(Spring) && [nil, '', "development", "test"].include?(ENV["RAILS_ENV"])
  require "bundler/setup"
  require "spring/binstub"
end

this simply makes it work. the reason it does not work with git is because of these lines

  Bundler.locked_gems.specs.find { |spec| spec.name == "spring" }&.tap do |spring|
    Gem.use_paths Gem.dir, Bundler.bundle_path.to_s, *Gem.path

but when I realized i don't need them to make spring work, I simply removed them.

(screen of my diff )

image

Hopefully this can help people use forked versions of spring in their projects. I just merged 3 of the PRs you guys did in my own fork, and it works flawlessly. and it's ready for ruby 3.4.0 release 👌🏼