Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How rails resolve multi-requests at the same time?

Tags:

Prepare for the test: sleep 10 in a action

Test: Open two tabs in the browser to visit the action

Result: When the second request is running, the first request finished and began rendering the view, but the view is still blank. After the second request finished too, the two requests finished rendering the view at the same time.

Conclusion: Rails is just one single instance. One request can only enter the action after the previous requests finish. But how to explain the response part? Why the multi-requests finish rendering the views at the same time?

like image 363
Keating Avatar asked Dec 25 '12 02:12

Keating


People also ask

How does Ruby on Rails handle multiple requests?

Rails automatically allows various operations to be performed at the same time. When using a threaded web server, such as the default Puma, multiple HTTP requests will be served simultaneously, with each request provided its own controller instance.

How many requests per second can Rails handle?

We see in Round 14, the common Rails setup (puma-mri-rails) generates 531 requests per second, while Roda, an extremely lightweight Ruby web framework, in combination with Sequel, generates about 7000 requests per second. Finally, we may ask the same question as after the first experiment.

What happens when multiple requests come to server?

Even if the request made from a new tab by the same user, the web server starts a new thread. (That is generally speaking. Although some imaginary server can perform them in queue in a single thread, but usually they are multithreaded and do not care about users) So, requests are performed simultaneously.

How web service handle multiple request?

Usually, each of the users sends an HTTP request for the page. The server receives the requests and delegates them to different workers (processes or threads). Depending on the URL given, the server reads a file and sends it back to the user.


2 Answers

WEBrick is multi-threaded but Rails developers hard-coded a mutex, so it can handle just one request at a time. You can monkey-patch Rails::Server and you are free to run a multi-threaded WEBrick.

Just note that WEBrick will be multithreaded only when config config.cache_classes = true and config.eager_load = true, which is typical to RAILS_ENV=production. This is because class reloading in development is not thread safe.

To get WEBrick fully multi-threaded in Rails 4.0, just add this to config/initializers/multithreaded_webrick.rb:

# Remove Rack::Lock so WEBrick can be fully multi-threaded. require 'rails/commands/server'  class Rails::Server   def middleware     middlewares = []     middlewares << [Rails::Rack::Debugger] if options[:debugger]     middlewares << [::Rack::ContentLength]      Hash.new middlewares   end end 

The offending code in rails/commands/server.rb that we got rid of is:

# FIXME: add Rack::Lock in the case people are using webrick. # This is to remain backwards compatible for those who are # running webrick in production. We should consider removing this # in development. if server.name == 'Rack::Handler::WEBrick'   middlewares << [::Rack::Lock] end 

It's not needed on Rails 4.2. It's concurrent out-of-the-box.

like image 144
Nowaker Avatar answered Oct 08 '22 00:10

Nowaker


Are you using a WEBrick server? That must be because your server is a single threaded server and is capable of fulfilling one request at a time (because of the single worker thread). Now in case of multiple requests, it runs the action part of the request and before running the view renderer it checks to see if there are any pending requests. Now if 10 requests are lined up, it would first complete all of them before actually rendering the views. When all of these requests are completed, the views would now be rendered sequentially.

You can switch to Passenger or Unicorn server if you want multi-threaded environment.

Hope that makes sense.

like image 27
atmaish Avatar answered Oct 08 '22 00:10

atmaish