From 457526d67fe02dd2962f9e8b13ba9b0c9c59f9c1 Mon Sep 17 00:00:00 2001 From: Maple Ong Date: Mon, 1 Feb 2021 16:03:53 -0500 Subject: [PATCH] Add documentation on interlock issue in Rails development mode (#2540) --- docs/rails_dev_mode.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 docs/rails_dev_mode.md diff --git a/docs/rails_dev_mode.md b/docs/rails_dev_mode.md new file mode 100644 index 0000000000..9f2eeaac86 --- /dev/null +++ b/docs/rails_dev_mode.md @@ -0,0 +1,29 @@ +# Running Puma in Rails Development Mode + +## "Loopback requests" + +Be cautious of "loopback requests", where a Rails application executes a request to a server that in turn, results in another request back to the same Rails application before the first request is completed. Having a loopback request will trigger [Rails' load interlock](https://guides.rubyonrails.org/threading_and_code_execution.html#load-interlock) mechanism. The load interlock mechanism prevents a thread from using Rails autoloading mechanism to load constants while the application code is still running inside another thread. + +This issue only occurs in the development environment as Rails' load interlock is not used in production environments. + +### Solutions + + +#### 1. Bypass Rails' load interlock with `.permit_concurrent_loads` + + Wrap the first request inside a block that will allow concurrent loads, [`ActiveSupport::Dependencies.interlock.permit_concurrent_loads`](https://guides.rubyonrails.org/threading_and_code_execution.html#permit-concurrent-loads). Anything wrapped inside the `.permit_concurrent_loads` block will bypass the load interlock mechanism, allowing new threads to access the Rails environment and boot properly. + + ###### Example + + ```ruby + response = ActiveSupport::Dependencies.interlock.permit_concurrent_loads do + # Your HTTP request code here. For example: + Faraday.post url, data: 'foo' + end + + do_something_with response + ``` + +#### 2. Use multiple processes on Puma + + Alternatively, you may also enable multiple single-threaded workers on Puma. By doing so, you are sidestepping the problem by creating multiple processes rather than new threads. However, this workaround is not ideal because debugging tools such as [byebug](https://github.com/deivid-rodriguez/byebug/issues/487) and [pry](https://github.com/pry/pry/issues/2153), work poorly with any multi-process web server.