Penso che questo effetto deriva dal modo in cui è scritto ActionController::Reloader
. Ecco ActionController::Reloader#call
da 2.3.3, nota il commento:
def call(env)
Dispatcher.reload_application
status, headers, body = @app.call(env)
# We do not want to call 'cleanup_application' in an ensure block
# because the returned Rack response body may lazily generate its data. This
# is for example the case if one calls
#
# render :text => lambda { ... code here which refers to application models ... }
#
# in an ActionController.
#
# Instead, we will want to cleanup the application code after the request is
# completely finished. So we wrap the body in a BodyWrapper class so that
# when the Rack handler calls #close during the end of the request, we get to
# run our cleanup code.
[status, headers, BodyWrapper.new(body)]
end
Dispatcher.reload_application
non toglie costanti auto-caricato, Dispatcher.cleanup_application
fa. BodyWrapper#close
è scritto con eventuali eccezioni in mente:
def close
@body.close if @body.respond_to?(:close)
ensure
Dispatcher.cleanup_application
end
Tuttavia, questo non aiuta, perché se @app.call
in ActionController::Reloader#call
genera un'eccezione, BodyWrapper
non ottiene istanziati, e Dispatcher.cleanup_application
non viene chiamato.
Immaginate il seguente scenario:
- posso apportare modifiche in uno dei miei file che colpisce chiamata API
- mi ha colpito chiamata API e vedere l'errore, a questo punto tutti i file, tra cui quello con un bug aren 't scaricati
- Faccio un codefix e colpito la stessa chiamata API per verificare se ha funzionato
- chiamata viene instradata allo stesso modo di prima, a vecchie classi/oggetti/modules. Questo getta stesso errore e ancora lascia costanti caricato in memoria
Ciò non accade quando i controllori tradizionali sollevano errori perché quelli sono gestite dai ActionController::Rescue
. Tali eccezioni non hanno colpito ActionController::Reloader
.
soluzione più semplice sarebbe quella di mettere clausola rescue fallback in API di routing middleware, qualche variazione di questo:
def call(env)
# route API call
resuce Exception
Dispatcher.cleanup_application
raise
end
notare che questa è la mia risposta alla domanda di 3 anni e ho seguito chiamata pila di 2.3.3 . Le versioni più recenti dei binari possono gestire le cose in modo diverso.
fonte
2012-08-22 13:52:16
Ho anche questo problema. –