Tôi nghĩ rằng hiệu ứng này xuất phát từ cách ActionController::Reloader
được viết. Dưới đây là ActionController::Reloader#call
từ 2.3.3, lưu ý những nhận xét:
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
không loại bỏ hằng số tự động nạp, Dispatcher.cleanup_application
làm. BodyWrapper#close
được viết với trường hợp ngoại lệ có thể có trong tâm trí:
def close
@body.close if @body.respond_to?(:close)
ensure
Dispatcher.cleanup_application
end
Tuy nhiên điều này không giúp đỡ, bởi vì nếu @app.call
trong ActionController::Reloader#call
ném một ngoại lệ, BodyWrapper
không được khởi tạo, và Dispatcher.cleanup_application
không được gọi.
Hãy tưởng tượng kịch bản sau đây:
- tôi có thay đổi trong một tác phẩm của tôi mà ảnh hưởng đến cuộc gọi API
- Tôi nhấn gọi API và thấy lỗi, vào thời điểm này tất cả các file bao gồm một với một lỗi aren 't bốc dỡ
- tôi thực hiện một codefix và nhấn cùng gọi API để kiểm tra xem nó làm việc
- cuộc gọi được chuyển theo cùng một cách như trước, đến các lớp học cũ/đối tượng/modules. Điều này ném lỗi tương tự và một lần nữa để lại các hằng số được nạp trong bộ nhớ
Điều này không xảy ra khi bộ điều khiển truyền thống tăng lỗi vì những điều khiển được xử lý bởi ActionController::Rescue
. Ngoại lệ như vậy không trúng ActionController::Reloader
.
giải pháp đơn giản nhất sẽ được đưa khoản cứu dự phòng vào API định tuyến trung gian, một số biến thể của việc này:
def call(env)
# route API call
resuce Exception
Dispatcher.cleanup_application
raise
end
Lưu ý rằng đây là câu trả lời của tôi cho câu hỏi cũ 3 năm và theo tiếng gọi của chồng 2.3.3 . Các phiên bản mới hơn của đường ray có thể xử lý mọi thứ khác nhau.
Nguồn
2012-08-22 13:52:16
Tôi cũng gặp sự cố này. –