puma is configured to run in single threaded, 2 workers, no queuing mode. See puma-config.rb
above.
Reference: until @todo.size - @waiting < @max - @spawned or @shutdown
Executing 3 requests to puma. First request will do sleep(10), next sleep(5), next sleep(2). First request should go to first worker, second to second, third wait until sleep(5) is done and execute on second worker.
Expected return order: 5, 2, 10
Client log:
$ curl http://localhost:4567/sleep/10 & sleep 1; curl http://localhost:4567/sleep/5 & sleep 1; curl http://localhost:4567/sleep/2
[1] 11390
[2] 11503
This request took: 5 sec
This request took: 2 sec
[2]+ Done curl http://localhost:4567/sleep/5
$ This request took: 10 sec
Puma log:
127.0.0.1 - - [09/Nov/2017:23:45:09 +0000] "GET /sleep/5 HTTP/1.1" 200 25 5.0012
127.0.0.1 - - [09/Nov/2017:23:45:12 +0000] "GET /sleep/2 HTTP/1.1" 200 25 2.0012
127.0.0.1 - - [09/Nov/2017:23:45:14 +0000] "GET /sleep/10 HTTP/1.1" 200 26 10.0050
Execution order as expected, second request sleep(5) was executing in parallel to first.
Reference:
while true
return if @shutdown
return if @waiting > 0
# If we can still spin up new threads and there
# is work queued, then accept more work until we would
# spin up the max number of threads.
return if @todo.size < @max - @spawned
Expected return order: 5, 2, 10
Client log:
$ curl http://localhost:4567/sleep/10 & sleep 1; curl http://localhost:4567/sleep/5 & sleep 1; curl http://localhost:4567/sleep/2
[1] 12647
[2] 12649
This request took: 2 sec
$ This request took: 10 sec
This request took: 5 sec
Puma log:
127.0.0.1 - - [09/Nov/2017:23:53:45 +0000] "GET /sleep/2 HTTP/1.1" 200 25 2.0072
127.0.0.1 - - [09/Nov/2017:23:53:51 +0000] "GET /sleep/10 HTTP/1.1" 200 26 10.0074
127.0.0.1 - - [09/Nov/2017:23:53:56 +0000] "GET /sleep/5 HTTP/1.1" 200 25 5.0025
As you can see thrid request got executed before second, and second ran only after sleep(10) was completed. In other words second requests gets blocked by the first request even though there are available workers.