6

I'm using puma and nxinx, and as far as I can tell it is only ever using a single thread even when I start it with the default of 16 threads or more. I've set up a fresh rails app, then gone through the set up described here:

http://blog.wiemann.name/rails-server

Which gives this sample nginx config:

upstream benchmarkapp.com {server unix:/tmp/benchmark_app.sock fail_timeout=0;}
server {
 server_name benchmarkapp.com;
 root /home/tristan/benchmark_app/public;
 try_files $uri/index.html $uri @benchmarkapp.com;
 location @benchmarkapp.com {
 proxy_redirect off;
 proxy_pass http://benchmarkapp.com;
 }
}

Then created a simple controller action which simply sleeps for 3 seconds, then renders "hello":

class WelcomeController < ApplicationController
  def index
    sleep(2)
    render :text => "hello"   
  end
end

Then I started puma with: puma -t 16 -b unix:///tmp/benchmark_app.sock -S /tmp/benchmark_app.state

once running, I hit it with 10 concurrent users using siege, and here is the result

 % siege -c 10 -t 60s http://benchmarkapp.com
** SIEGE 2.70
** Preparing 10 concurrent users for battle.
The server is now under siege...
HTTP/1.1 200   2.04 secs:      25 bytes ==> /
HTTP/1.1 200   4.05 secs:      25 bytes ==> /
HTTP/1.1 200   6.06 secs:      25 bytes ==> /
HTTP/1.1 200   8.08 secs:      25 bytes ==> /
HTTP/1.1 200  10.09 secs:      25 bytes ==> /

Which is precisely what I would expect to see if the app were running single threaded. Take the first two requests. They arrive at roughly the same time. The first takes two seconds, so far so good. But the second, third, ... through the 10th all have to to wait an additional 2 seconds for each request before it. In fact, if I restart puma with only 1 thread I get exactly this result.

What am I doing wrong here? How can I get the server to actually use all of the threads that puma spawns? If everything works properly I expect to see:

 % siege -c 10 -t 60s http://benchmarkapp.com
** SIEGE 2.70
** Preparing 10 concurrent users for battle.
The server is now under siege...
HTTP/1.1 200   2.04 secs:      25 bytes ==> /
HTTP/1.1 200   2.05 secs:      25 bytes ==> /
HTTP/1.1 200   2.03 secs:      25 bytes ==> /
HTTP/1.1 200   2.01 secs:      25 bytes ==> /
HTTP/1.1 200   2.06 secs:      25 bytes ==> /

How can I make this happen?

jm3
  • 2,405
  • 1
  • 14
  • 10
DrFredEdison
  • 261
  • 4
  • 11
  • 1
    Why are people voting this question down? Is there some way I can improve it? Has it been answered elsewhere? – DrFredEdison May 23 '14 at 14:22
  • I have the exact same question !!! I've been trying to simulate different ways to try to get it to use multiple threads (by using external API calls that go on for 10 seconds, huge file read operations, etc) and nothing seems to work. It always uses 1 thread only. I don't see any benefit of Puma yet. Stumbled upon this question which is exactly my situation. – Vishnu Narang Jan 18 '19 at 13:25

1 Answers1

0

After doing a lot of research online and trying to figure out how to get Puma to actually use threads, I finally figured out.

You can use config.allow_concurrency = true in your application config. This will remove the use of Rack::Lock middleware which is responsible for thread-safety in ruby using GIL (it ensures that only 1 thread is running at a time).

To verify your config, use rake middleware and ensure you DON'T see use Rack::Lock in the list.