Skip to content

Commit a417041

Browse files
authored
[ruby/grape] Hardcode Puma to 5 threads (#10389)
Also extract most logic to a boot.rb, similarly to other Ruby frameworks.
1 parent b3ccafd commit a417041

File tree

6 files changed

+99
-110
lines changed

6 files changed

+99
-110
lines changed

frameworks/Ruby/grape/boot.rb

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
require 'erb'
2+
require 'active_record'
3+
require 'yaml'
4+
5+
MAX_PK = 10_000
6+
ID_RANGE = (1..MAX_PK).freeze
7+
ALL_IDS = ID_RANGE.to_a
8+
QUERIES_MIN = 1
9+
QUERIES_MAX = 500
10+
11+
Bundler.require :default
12+
13+
db_config = YAML.load(ERB.new(File.read('config/database.yml')).result)[ENV['RACK_ENV']]
14+
ActiveRecord::Base.establish_connection(db_config)
15+
16+
class World < ActiveRecord::Base
17+
self.table_name = 'World'
18+
end
19+
20+
module Acme
21+
class HelloWorld < Grape::API
22+
get '/json' do
23+
{message:'Hello, World!'}
24+
end
25+
end
26+
27+
class PlainText < Grape::API
28+
content_type :plain, 'text/plain'
29+
format :plain
30+
31+
get '/plaintext' do
32+
'Hello, World!'
33+
end
34+
end
35+
36+
class DatabaseQueries < Grape::API
37+
logger nil
38+
helpers do
39+
def bounded_queries
40+
queries = params[:queries].to_i
41+
queries.clamp(QUERIES_MIN, QUERIES_MAX)
42+
end
43+
44+
# Return a random number between 1 and MAX_PK
45+
def rand1
46+
rand(MAX_PK).succ
47+
end
48+
end
49+
50+
get '/db' do
51+
ActiveRecord::Base.with_connection do
52+
World.find(rand1).attributes
53+
end
54+
end
55+
56+
get '/query' do
57+
ActiveRecord::Base.with_connection do
58+
ALL_IDS.sample(bounded_queries).map do |id|
59+
World.find(id)
60+
end
61+
end
62+
end
63+
64+
get '/updates' do
65+
worlds =
66+
ActiveRecord::Base.with_connection do
67+
ALL_IDS.sample(bounded_queries).map do |id|
68+
world = World.find(id)
69+
new_value = rand1
70+
new_value = rand1 while new_value == world.randomNumber
71+
world.update_columns(randomNumber: new_value)
72+
world
73+
end
74+
end
75+
end
76+
end
77+
78+
class API < Grape::API
79+
before do
80+
header 'Date', Time.now.httpdate if defined?(Puma)
81+
header 'Server', 'grape'
82+
end
83+
logger nil
84+
content_type :json, 'application/json'
85+
format :json
86+
87+
mount ::Acme::HelloWorld
88+
mount ::Acme::PlainText
89+
mount ::Acme::DatabaseQueries
90+
end
91+
end

frameworks/Ruby/grape/config.ru

Lines changed: 1 addition & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,94 +1,2 @@
1-
require 'erb'
2-
require 'active_record'
3-
require 'yaml'
4-
require_relative 'config/auto_tune'
5-
6-
MAX_PK = 10_000
7-
ID_RANGE = (1..MAX_PK).freeze
8-
ALL_IDS = ID_RANGE.to_a
9-
QUERIES_MIN = 1
10-
QUERIES_MAX = 500
11-
12-
Bundler.require :default
13-
14-
db_config = YAML.load(ERB.new(File.read('config/database.yml')).result)[ENV['RACK_ENV']]
15-
ActiveRecord::Base.establish_connection(db_config)
16-
17-
class World < ActiveRecord::Base
18-
self.table_name = 'World'
19-
end
20-
21-
module Acme
22-
class HelloWorld < Grape::API
23-
get '/json' do
24-
{message:'Hello, World!'}
25-
end
26-
end
27-
28-
class PlainText < Grape::API
29-
content_type :plain, 'text/plain'
30-
format :plain
31-
32-
get '/plaintext' do
33-
'Hello, World!'
34-
end
35-
end
36-
37-
class DatabaseQueries < Grape::API
38-
logger nil
39-
helpers do
40-
def bounded_queries
41-
queries = params[:queries].to_i
42-
queries.clamp(QUERIES_MIN, QUERIES_MAX)
43-
end
44-
45-
# Return a random number between 1 and MAX_PK
46-
def rand1
47-
rand(MAX_PK).succ
48-
end
49-
end
50-
51-
get '/db' do
52-
ActiveRecord::Base.with_connection do
53-
World.find(rand1).attributes
54-
end
55-
end
56-
57-
get '/query' do
58-
ActiveRecord::Base.with_connection do
59-
ALL_IDS.sample(bounded_queries).map do |id|
60-
World.find(id)
61-
end
62-
end
63-
end
64-
65-
get '/updates' do
66-
worlds =
67-
ActiveRecord::Base.with_connection do
68-
ALL_IDS.sample(bounded_queries).map do |id|
69-
world = World.find(id)
70-
new_value = rand1
71-
new_value = rand1 while new_value == world.randomNumber
72-
world.update_columns(randomNumber: new_value)
73-
world
74-
end
75-
end
76-
end
77-
end
78-
79-
class API < Grape::API
80-
before do
81-
header 'Date', Time.now.httpdate if defined?(Puma)
82-
header 'Server', 'grape'
83-
end
84-
logger nil
85-
content_type :json, 'application/json'
86-
format :json
87-
88-
mount ::Acme::HelloWorld
89-
mount ::Acme::PlainText
90-
mount ::Acme::DatabaseQueries
91-
end
92-
end
93-
1+
require_relative 'boot'
942
run Acme::API

frameworks/Ruby/grape/config/database.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ production:
55
database: hello_world
66
username: benchmarkdbuser
77
password: benchmarkdbpass
8-
pool: 3
8+
pool: <%= ENV.fetch('MAX_THREADS') %>
99
timeout: 5000

frameworks/Ruby/grape/config/puma.rb

Lines changed: 0 additions & 13 deletions
This file was deleted.

frameworks/Ruby/grape/grape-iodine.dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@ ADD ./ /grape
1414
WORKDIR /grape
1515

1616
RUN bundle config set with 'iodine'
17-
RUN bundle install --jobs=4 --gemfile=/grape/Gemfile
17+
RUN bundle install --jobs=8 --gemfile=/grape/Gemfile
1818

1919
ENV RACK_ENV=production
20+
ENV MAX_THREADS=1
2021

2122
EXPOSE 8080
2223

frameworks/Ruby/grape/grape.dockerfile

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@ ADD ./ /grape
1212
WORKDIR /grape
1313

1414
RUN bundle config set with 'puma'
15-
RUN bundle install --jobs=4 --gemfile=/grape/Gemfile
15+
RUN bundle install --jobs=8 --gemfile=/grape/Gemfile
1616

1717
ENV WEB_CONCURRENCY=auto
18+
ENV MAX_THREADS=5
19+
1820
EXPOSE 8080
1921

20-
CMD bundle exec puma -C config/puma.rb -b tcp://0.0.0.0:8080 -e production
22+
CMD bundle exec puma -b tcp://0.0.0.0:8080 -e production

0 commit comments

Comments
 (0)