Skip to content

Commit

Permalink
Add Spring.reset_on_env
Browse files Browse the repository at this point in the history
Spring needs to restart when certain important environment variables
change (eg. DATABASE_URL). Without this, comamnds connect to a stale
application instance that has been booted with incorrect config.

Configuration must be set in config/spring_client.rb.
  • Loading branch information
gmcgibbon committed Nov 21, 2023
1 parent 8b285d5 commit 23848bc
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 4 deletions.
12 changes: 10 additions & 2 deletions lib/spring/client/run.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def run
def boot_server
env.socket_path.unlink if env.socket_path.exist?

pid = Process.spawn(gem_env, env.server_command, out: File::NULL)
pid = Process.spawn(server_process_env, env.server_command, out: File::NULL)
timeout = Time.now + BOOT_TIMEOUT

@server_booted = true
Expand Down Expand Up @@ -107,6 +107,14 @@ def gem_env
}
end

def reset_env
ENV.slice(*Spring.reset_on_env)
end

def server_process_env
reset_env.merge(gem_env)
end

def stop_server
server.close
@server = nil
Expand All @@ -132,7 +140,7 @@ def verify_server_version

def connect_to_application(client)
server.send_io client
send_json server, "args" => args, "default_rails_env" => default_rails_env
send_json server, "args" => args, "default_rails_env" => default_rails_env, "reset_env" => reset_env

if IO.select([server], [], [], CONNECT_TIMEOUT)
server.gets or raise CommandNotFound
Expand Down
4 changes: 4 additions & 0 deletions lib/spring/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ def after_fork(&block)
after_fork_callbacks << block
end

def reset_on_env
@reset_on_env ||= []
end

def verify_environment
application_root_path
end
Expand Down
11 changes: 9 additions & 2 deletions lib/spring/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,15 @@ def serve(client)
app_client = client.recv_io
command = JSON.load(client.read(client.gets.to_i))

args, default_rails_env = command.values_at('args', 'default_rails_env')
args, default_rails_env, reset_env = command.values_at('args', 'default_rails_env', 'reset_env')

if Spring.command?(args.first)
application = @applications[rails_env_for(args, default_rails_env)]
reset_if_env_changed(application, reset_env)

log "running command #{args.first}"
client.puts
client.puts @applications[rails_env_for(args, default_rails_env)].run(app_client)
client.puts application.run(app_client)
else
log "command not found #{args.first}"
client.close
Expand Down Expand Up @@ -136,6 +139,10 @@ def set_process_title

private

def reset_if_env_changed(application, reset_env)
application.stop if ENV.slice(*reset_env.keys) != reset_env
end

def default_env
Env.new(log_file: default_log_file)
end
Expand Down

0 comments on commit 23848bc

Please sign in to comment.