Skip to content

Instantly share code, notes, and snippets.

@ivanpesin
Last active November 10, 2017 00:04
Show Gist options
  • Save ivanpesin/f40a76e51a60a83f1190113fdecddaa5 to your computer and use it in GitHub Desktop.
Save ivanpesin/f40a76e51a60a83f1190113fdecddaa5 to your computer and use it in GitHub Desktop.
require 'sinatra'
configure { set :server, :puma }
get '/' do
"Hello World!"
end
get '/sleep/:sec' do
puts "Sleeping for #{params['sec']}"
sleep params['sec'].to_i
puts "Done"
"This request took: #{params['sec']} sec"
end
require 'rubygems'
require './app'
run Sinatra::Application
queue_requests false
threads 1, 1
workers 2
#bind 'tcp://0.0.0.0:8080'
quiet false

Testing puma old vs condition

puma is configured to run in single threaded, 2 workers, no queuing mode. See puma-config.rb above.

Old condition

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.

New condition

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment