Response to HTTP request at production mode in rails - ruby-on-rails

If I run rails server in production environment by rails server -e production, rails runs as a single-threaded application.
So will it respond to one HTTP request at a time or more requests at a time?

It depend on which server you are using to run rails application .
For instance if you are using Webrick server (which is single threaded by default)then you will handle one request at a time but if you use passenger server then it will create instances of your application (which is configurable), then you can handle multiple request at a time

Since it is single-threaded so one request can only enter the action after the previous requests finish. But it can respond to multiple requests at a time.

Related

Rails - is new instance of Rails application created for every http request in nginx/passenger

I have deployed a Rails app at Engineyard in production and staging environment. I am curious to know if every HTTP request for my app initializes new instance of my Rails App or not?
Rails is stateless, which means each request to a Rails application has its own environment and variables that are unique to that request. So, a qualified "yes", each request starts a new instance[1] of your app; you can't determine what happened in previous requests, or other requests happening at the same time. But, bear in mind the app will be served from a fixed set of workers.
With Rails on EY, you will be running something like thin or unicorn as the web server. This will have a defined number of workers, let's say 5. Each worker can handle only one request at a time, because that's how rails works. So if your requests take 200ms each, that means you can handle approximately 5 requests per second, for each worker. If one request takes a long time (a few seconds), that worker is not available to take any other requests. Workers are typically not created and removed on Engineyard; they are set up and run continuously until you re-deploy, though for something like Heroku, your app may not have any workers (dynos) and if there are no requests coming in it will have to spin up.
[1] I'm defining instance, as in, a new instance of the application class. Each model and class will be re-instantiated and the #request and #session built from scratch.
According to what I have understood. No, It will definitely not initialize new instance for every request. Then again two questions might arise.
How can multiple user simultaneously login and access my system without interference?
Even though one user takes up too much processing time, how is another user able to access other features.
Answer to the first question is that HTTP is stateless, everything is stored in session, which is in cookie, which is in client machine and not in server. So when you send a HTTP request for a logged in user, browser actually sends the HTTP request with the required credentials/user information from clients cookies to the server without the user knowing it. Multiple requests are just queued and served accordingly. Since our server are very very fast, I feel its just processing instantly.
For the second query, your might might be concurrency. The server you are using (nginx, passenger) has the capacity to serve multiple request at same time. Even if our server might be busy for a particular user(Lets say for video processing), it might serve another request through another thread so that multiple user can simultaneously access our system.

avoid dead locks in recursive web calls on rails 3

let's say I've sent a get request to some action in some controller in rails.
and in that action I'm sending requests to get web pages from another server.
for example :
open("http://example.com/myexample.xml")
when i call this function using localhost as a parameter the site requests it self so the server goes in a dead lock state and stops
any ideas to get page of localhost without making the requests queued on the main thread ?
the same problem happens when the main thread sleeps or get busy to process a request and another request comes to the server ... it waits till the first request is finished.
any solutions for that ?
You can run another server instance:
rails s # http://localhost:3000
rails s -p 3001 # http://localhost:3001
Then you can send requests from localhost:3001 to localhost:3000 or on the contrary.
I prefer to use unicorn as second server
rails s # http://localhost:3000
unicorn # http://localhost:8080

Rails dev server that allows multiple requests?

I would like to be able to make a request to a ruby method on a rails app after calling a long-running request that would run in parallel to the request. I know that using a background processing gem would make this possible, however is there a dev server that handles more than one request?

How is my single-threaded Rails app handling concurrent requests?

I have a single-threaded Rails app running on thin in single-threaded mode on Heroku Cedar.
While I do a huge POST request (a file upload) that takes more than a minute, I can do other GET requests at the same time.
Heroku support assures me that their routing layer is not storing the request and then sending it all at once (which is the behavior of many proxies, such as nginx). They insist that my app is handling concurrent requests.
What's going on here?
Thin is built on top of EventMachine, which provides event-based IO.
This means that Thin does async receiving of your POST request, while serving GET requests in the meanwhile. When POST data is uploaded, Thin then goes on to pass it to Rails (where it is processed synchronously and blocks other requests until finished).

Why does the server need to restart when a model file is updated?

I'd like to know why is there a need to restart the server (Mongrel/WEBrick) every time a model file is updated? I know it doesn't get loaded in if you don't do it - but is there any documentation out there that would explain why it does so?
Thanks!
Development environments do not require you to restart the server if you change a model. They will reload the environment for each request if necessary.
Production environments are a different story. A Rails server (mongrel/passenger/webrick/etc) running in a production environment will only load your Rails environment once when the process is started. This takes a couple of seconds, as you might notice when starting the console which also loads your Rails environment. To avoid this overhead for each request the server will spawn a new thread from the loaded environment to handle each incoming request.
Because the server only responds to HTTP requests, and the usual signals. There's no good way to force an environment reload beyond always loading a fresh environment (like a development environment, or restarting the server.

Resources