spring
spring copied to clipboard
Cannot detect if Spring is running
The docs say:
From within your code, you can check whether Spring is active with
if defined?(Spring).
But Spring is defined when running rails s even without Spring.
With this code inside an initializer:
if defined?(Spring)
puts "Spring is defined (only shown on first run)"
Spring.after_fork do
puts "After fork"
end
else
puts "Spring is not defined"
end
The output from rails test is:
Spring is defined (only shown on first run)
Running via Spring preloader in process 21343
After fork
Which is as expected. Running DISABLE_SPRING=1 rails test gives:
Spring is not defined
Which is also the expected outcome.
However, running either rails s or DISABLE_SPRING=1 rails s gives the same output:
Spring is defined (only shown on first run)
In short, the documented check for whether Spring is active or not seems to return a false positive for certain Rails commands.
I've felt this pain as well. There are a number of scenarios where you need to be able to reliably hook into whether you're in a forked spring process or not in order to properly initializer connections. For example, the ruby grpc client has a check to make sure you don't initialize a connection in a child process when you've already done so in a parent process.
I've seen scenarios where the Spring.after_fork hook doesn't get invoked reliably. Unclear if this is a bug with the hook invocation, or if Spring is present (and defined) but child processes aren't being forked.
In my Rails 7.0.7.2 app Spring is always loaded, even with DISABLE_SPRING=true, and even with require: false in the Gemfile, and as a result there is no way to detect when commands are running against Spring, or not.
In my case, another gem was loading Spring by doing require "spring/commands" even when not running in Spring. For me, it worked to check defined?(Spring::Application) instead. If you want to be really sure whether you're running in Spring, you could check defined?(Spring::Application) && caller.any? {|c| c.start_with?(Spring.const_source_location('Application')&.first) }