@@ -133,73 +133,88 @@ def run
133
133
end
134
134
end
135
135
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
+
136
154
def serve ( client )
137
155
log "got client"
138
156
manager . puts
139
157
140
158
stdout , stderr , stdin = streams = 3 . times . map { client . recv_io }
141
159
[ STDOUT , STDERR , STDIN ] . zip ( streams ) . each { |a , b | a . reopen ( b ) }
142
160
143
- preload unless preloaded?
161
+ client_args , client_env = JSON . load ( client . read ( client . gets . to_i ) ) . values_at ( "args" , "env" )
144
162
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 )
155
167
156
- pid = fork {
157
- IGNORE_SIGNALS . each { |sig | trap ( sig , "DEFAULT" ) }
158
- trap ( "TERM" , "DEFAULT" )
168
+ connect_database
169
+ setup command
159
170
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
162
175
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" )
165
179
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
168
182
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
176
190
177
- connect_database
178
- srand
191
+ connect_database
192
+ srand
179
193
180
- invoke_after_fork_callbacks
181
- shush_backtraces
194
+ invoke_after_fork_callbacks
195
+ shush_backtraces
182
196
183
- command . call
184
- }
197
+ command . call
198
+ }
199
+ end
185
200
186
201
disconnect_database
187
202
reset_streams
188
203
189
- log "forked #{ pid } "
190
- manager . puts pid
204
+ log "forked #{ @ pid} "
205
+ manager . puts @ pid
191
206
192
- wait pid , streams , client
207
+ wait @ pid, streams , client
193
208
rescue Exception => e
194
209
log "exception: #{ e } "
195
- manager . puts unless pid
210
+ manager . puts unless @ pid
196
211
197
212
if streams && !e . is_a? ( SystemExit )
198
213
print_exception ( stderr , e )
199
214
streams . each ( &:close )
200
215
end
201
216
202
- client . puts ( 1 ) if pid
217
+ client . puts ( 1 ) if @ pid
203
218
client . close
204
219
end
205
220
0 commit comments