From 23848bccc5c2cdbee1b39e1f6c0f6de0a31d2717 Mon Sep 17 00:00:00 2001 From: Gannon McGibbon Date: Tue, 21 Nov 2023 15:14:52 -0600 Subject: [PATCH] Add Spring.reset_on_env 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. --- lib/spring/client/run.rb | 12 ++++++++++-- lib/spring/configuration.rb | 4 ++++ lib/spring/server.rb | 11 +++++++++-- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/lib/spring/client/run.rb b/lib/spring/client/run.rb index c5fe1dd5..7c5c607c 100644 --- a/lib/spring/client/run.rb +++ b/lib/spring/client/run.rb @@ -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 @@ -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 @@ -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 diff --git a/lib/spring/configuration.rb b/lib/spring/configuration.rb index cbd3d5e3..4534ef4f 100644 --- a/lib/spring/configuration.rb +++ b/lib/spring/configuration.rb @@ -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 diff --git a/lib/spring/server.rb b/lib/spring/server.rb index c3ab20e6..14dbf1c8 100644 --- a/lib/spring/server.rb +++ b/lib/spring/server.rb @@ -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 @@ -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