@@ -133,73 +133,88 @@ def run
133133 end
134134 end
135135
136+ def with_env_vars ( env )
137+ # Allowed are keys currently not in ENV...
138+ allowed_keys = env . keys - ENV . keys
139+ # ...and ENV-keys whose values have not changed since the start of spring
140+ allowed_keys += original_env . select { |k , v | ENV [ k ] == v } . keys
141+ # never allowed:
142+ allowed_keys -= %w( RUBYOPT RUBY_ROOT BUNDLE_GEMFILE GEM_ROOT GEM_HOME GEM_PATH )
143+ allowed_keys . uniq!
144+
145+ allowed_keys . each { |k | ENV [ k ] = env [ k ] }
146+
147+ yield
148+ ensure
149+ allowed_keys . each do |k |
150+ original_env . has_key? ( k ) ? ENV [ k ] = original_env [ k ] : ENV . delete ( k )
151+ end
152+ end
153+
136154 def serve ( client )
137155 log "got client"
138156 manager . puts
139157
140158 stdout , stderr , stdin = streams = 3 . times . map { client . recv_io }
141159 [ STDOUT , STDERR , STDIN ] . zip ( streams ) . each { |a , b | a . reopen ( b ) }
142160
143- preload unless preloaded?
161+ client_args , client_env = JSON . load ( client . read ( client . gets . to_i ) ) . values_at ( "args" , "env" )
144162
145- args , env = JSON . load ( client . read ( client . gets . to_i ) ) . values_at ( "args" , "env" )
146- command = Spring . command ( args . shift )
147-
148- connect_database
149- setup command
150-
151- if Rails . application . reloaders . any? ( &:updated? )
152- ActionDispatch ::Reloader . cleanup!
153- ActionDispatch ::Reloader . prepare!
154- end
163+ @pid = nil
164+ with_env_vars ( client_env ) do
165+ preload unless preloaded?
166+ command = Spring . command ( client_args . shift )
155167
156- pid = fork {
157- IGNORE_SIGNALS . each { |sig | trap ( sig , "DEFAULT" ) }
158- trap ( "TERM" , "DEFAULT" )
168+ connect_database
169+ setup command
159170
160- ARGV . replace ( args )
161- $0 = command . process_title
171+ if Rails . application . reloaders . any? ( &:updated? )
172+ ActionDispatch ::Reloader . cleanup!
173+ ActionDispatch ::Reloader . prepare!
174+ end
162175
163- # Delete all env vars which are unchanged from before spring started
164- original_env . each { |k , v | ENV . delete k if ENV [ k ] == v }
176+ @pid = fork {
177+ IGNORE_SIGNALS . each { |sig | trap ( sig , "DEFAULT" ) }
178+ trap ( "TERM" , "DEFAULT" )
165179
166- # Load in the current env vars, except those which *were* changed when spring started
167- env . each { | k , v | ENV [ k ] ||= v }
180+ ARGV . replace ( client_args )
181+ $0 = command . process_title
168182
169- # requiring is faster, so if config.cache_classes was true in
170- # the environment's config file, then we can respect that from
171- # here on as we no longer need constant reloading.
172- if @original_cache_classes
173- ActiveSupport ::Dependencies . mechanism = :require
174- Rails . application . config . cache_classes = true
175- end
183+ # requiring is faster, so if config.cache_classes was true in
184+ # the environment's config file, then we can respect that from
185+ # here on as we no longer need constant reloading.
186+ if @original_cache_classes
187+ ActiveSupport ::Dependencies . mechanism = :require
188+ Rails . application . config . cache_classes = true
189+ end
176190
177- connect_database
178- srand
191+ connect_database
192+ srand
179193
180- invoke_after_fork_callbacks
181- shush_backtraces
194+ invoke_after_fork_callbacks
195+ shush_backtraces
182196
183- command . call
184- }
197+ command . call
198+ }
199+ end
185200
186201 disconnect_database
187202 reset_streams
188203
189- log "forked #{ pid } "
190- manager . puts pid
204+ log "forked #{ @ pid} "
205+ manager . puts @ pid
191206
192- wait pid , streams , client
207+ wait @ pid, streams , client
193208 rescue Exception => e
194209 log "exception: #{ e } "
195- manager . puts unless pid
210+ manager . puts unless @ pid
196211
197212 if streams && !e . is_a? ( SystemExit )
198213 print_exception ( stderr , e )
199214 streams . each ( &:close )
200215 end
201216
202- client . puts ( 1 ) if pid
217+ client . puts ( 1 ) if @ pid
203218 client . close
204219 end
205220
0 commit comments