Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions frameworks/rails/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ ENV RUBY_MN_THREADS=1
ENV RACK_ENV=production
ENV WEB_CONCURRENCY=auto
ENV RAILS_MAX_THREADS=3
ENV MAX_IO_THREADS=5

WORKDIR /app

Expand Down
2 changes: 1 addition & 1 deletion frameworks/rails/Gemfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
source 'https://rubygems.org'

gem 'rails', '~> 8.0'
gem 'puma', '~> 7.2'
gem 'puma', '~> 8.0'
gem 'pg', '~> 1.5'
gem 'bootsnap', require: false
gem 'connection_pool'
6 changes: 3 additions & 3 deletions frameworks/rails/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ GEM
psych (5.3.1)
date
stringio
puma (7.2.0)
puma (8.0.1)
nio4r (~> 2.0)
racc (1.8.1)
rack (3.2.6)
Expand Down Expand Up @@ -208,7 +208,7 @@ DEPENDENCIES
bootsnap
connection_pool
pg (~> 1.5)
puma (~> 7.2)
puma (~> 8.0)
rails (~> 8.0)

CHECKSUMS
Expand Down Expand Up @@ -260,7 +260,7 @@ CHECKSUMS
prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193
prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85
psych (5.3.1) sha256=eb7a57cef10c9d70173ff74e739d843ac3b2c019a003de48447b2963d81b1974
puma (7.2.0) sha256=bf8ef4ab514a4e6d4554cb4326b2004eba5036ae05cf765cfe51aba9706a72a8
puma (8.0.1) sha256=7b94e50c07655718c1fb8ae41a11fc06c7d61293208b3aa608ff71a46d3ad37c
racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f
rack (3.2.6) sha256=5ed78e1f73b2e25679bec7d45ee2d4483cc4146eb1be0264fc4d94cb5ef212c2
rack-session (2.1.2) sha256=595434f8c0c3473ae7d7ac56ecda6cc6dfd9d37c0b2b5255330aa1576967ffe8
Expand Down
68 changes: 42 additions & 26 deletions frameworks/rails/config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,46 @@

Bundler.require(*Rails.groups)

# Catch unknown HTTP methods, routing errors, and mark /upload as binary
class MethodGuard
VALID_METHODS = %w[GET HEAD POST PUT DELETE PATCH OPTIONS TRACE].to_set.freeze

def initialize(app)
@app = app
end

def call(env)
unless VALID_METHODS.include?(env['REQUEST_METHOD'])
return [405, { 'content-type' => 'text/plain' }, ['Method Not Allowed']]
end
# Mark /upload as binary so Rack skips form parameter parsing
if env['PATH_INFO'] == '/upload'
env['CONTENT_TYPE'] = 'application/octet-stream'
end
@app.call(env)
rescue => e
if e.class.name.include?('UnknownHttpMethod') || e.class.name.include?('RoutingError')
[400, { 'content-type' => 'text/plain' }, ['Bad Request']]
else
raise
end
end
end

# Threads marked as IO bound are allowed to go over Puma's max thread limit.
class MarkAsIOBoundThreads
def initialize(app)
@app = app
end

def call(env)
if env['PATH_INFO'].start_with?('/baseline')
env["puma.mark_as_io_bound"].call
end
@app.call(env)
end
end

class BenchmarkApp < Rails::Application
config.load_defaults Rails::VERSION::STRING.to_f
config.eager_load = true
Expand All @@ -25,32 +65,8 @@ class BenchmarkApp < Rails::Application

# Add gzip support
config.middleware.insert 0, Rack::Deflater

# Catch unknown HTTP methods, routing errors, and mark /upload as binary
config.middleware.insert 0, Class.new {
VALID_METHODS = %w[GET HEAD POST PUT DELETE PATCH OPTIONS TRACE].to_set.freeze

def initialize(app)
@app = app
end

def call(env)
unless VALID_METHODS.include?(env['REQUEST_METHOD'])
return [405, { 'content-type' => 'text/plain' }, ['Method Not Allowed']]
end
# Mark /upload as binary so Rack skips form parameter parsing
if env['PATH_INFO'] == '/upload'
env['CONTENT_TYPE'] = 'application/octet-stream'
end
@app.call(env)
rescue => e
if e.class.name.include?('UnknownHttpMethod') || e.class.name.include?('RoutingError')
[400, { 'content-type' => 'text/plain' }, ['Bad Request']]
else
raise
end
end
}
config.middleware.insert 0, MethodGuard
config.middleware.insert 0, MarkAsIOBoundThreads

# Silence logging
config.logger = nil
Expand Down
1 change: 1 addition & 0 deletions frameworks/rails/config/puma.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
thread_count = ENV.fetch('RAILS_MAX_THREADS', 4).to_i
threads thread_count, thread_count
max_io_threads ENV.fetch("MAX_IO_THREADS", 10).to_i

tls_cert_path = ENV.fetch('TLS_CERT', '/certs/server.crt')
tls_key_path = ENV.fetch('TLS_KEY', '/certs/server.key')
Expand Down