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

Environment variables changed by rails cannot be reloaded #653

Open
mildred opened this issue Sep 28, 2021 · 3 comments · May be fixed by #654
Open

Environment variables changed by rails cannot be reloaded #653

mildred opened this issue Sep 28, 2021 · 3 comments · May be fixed by #654

Comments

@mildred
Copy link

mildred commented Sep 28, 2021

The following piece of code handle environment variable reloads in Spring

# Delete all env vars which are unchanged from before spring started
original_env.each { |k, v| ENV.delete k if ENV[k] == v }
# Load in the current env vars, except those which *were* changed when spring started
env.each { |k, v| ENV[k] ||= v }

What it does is:

  • iterate over environment variables from when spring was started and remove those that rails did not change
  • iterate over client environment variables and if those are not present in the environment already, replace them

My problem is that I have a Rails application where there is an environment variable that triggers if the app is in master mode or slave mode. I use ENV! to manage environment variable, and if a variable is not set, ENV! sets a default value. The following sequence of events cause an issue:

  • spring server starts without the MASTER environment variable
  • app sets MASTER=false which is its default value
  • some time later...
  • I start the app again with MASTER=true on the command-line
  • Spring server receives a client request with MASTER=true
  • the process above is followed:
    • it considers MASTER to be unset when the spring server started but it has now MASTER=false. It received a client request with MASTER=true
    • it does not removes MASTER from the environment because it sees the variable changed (fron no value to false)
    • it does not replace MASTER=false with MASTER=true because it already has a value.
  • the app is started in slave mode despite having specified MASTER=true on the command-line.

I don't know the rationale behind this code, but in some cases it is completely wrong.

I believe this might be a reason behing the #420 issue

@jasonperrone
Copy link

@mildred Can I ask a question? Do you think this would cause this problem I am facing since upgrading Spring from 2.1.1. I have the following command:

bin/rails db:drop RAILS_ENV=test DATABASE_URL=test_lib

Since upgrading Spring, the DATABASE_URL env variable is being ignored. Just wondering if I need to report a new issue or is this the same issue.

@pboling
Copy link

pboling commented Aug 31, 2023

I'm having a similar issue with MYSQL_SOCKET being ignored, even though I can see it is set after Spring forks.

Running via Spring preloader in process 41869
ENV['MYSQL_SOCKET']: "/tmp/mysql.sock"

An error occurred while loading ./spec/jobs/my_job_spec.rb.
Failure/Error: ActiveRecord::Migration.maintain_test_schema!

ActiveRecord::ConnectionNotEstablished:
  Can't connect to local MySQL server through socket '' (2)
# ./spec/support/config/migrations.rb:3:in `<top (required)>'
# ./spec/rails_helper.rb:18:in `<top (required)>'
# ./spec/jobs/my_job_spec.rb:1:in `<top (required)>'
# -e:1:in `<main>'
# ------------------
# --- Caused by: ---
# Mysql2::Error::ConnectionError:
#   Can't connect to local MySQL server through socket '' (2)

where the file spec/support/config/migrations.rb looks like:

puts "ENV['MYSQL_SOCKET']: #{ENV['MYSQL_SOCKET'].inspect}"
# Ensure that all migrations have been run before running specs
ActiveRecord::Migration.maintain_test_schema!

I'm not sure how this is possible. The ENV variables are set and managed by direnv in an .envrc file.
I'm on Rails 7.0.7.2 and spring 4.1.1

@pboling
Copy link

pboling commented Aug 31, 2023

For me it was a case of two different spring processes running. One in the foreground in my terminal, which worked, and responded to commands also sent from the terminal, and the other was running hidden in RubyMine, and it had not been restarted when I was manually restarting the one in my Terminal.
See: https://www.jetbrains.com/help/ruby/spring.html#stop_spring

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

Successfully merging a pull request may close this issue.

3 participants