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
22 changes: 22 additions & 0 deletions frameworks/rage/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
FROM ruby:4.0-slim

RUN apt-get update && \
apt-get install -y --no-install-recommends build-essential libsqlite3-dev libyaml-dev libjemalloc2 && \
rm -rf /var/lib/apt/lists/*

# Use Jemalloc
ENV LD_PRELOAD=libjemalloc.so.2

ENV RUBY_YJIT_ENABLE=1
ENV RACK_ENV=production

WORKDIR /app

COPY Gemfile .
RUN bundle install --jobs=$(nproc)

COPY . .

EXPOSE 8080

CMD ["bundle", "exec", "rage", "server", "-p", "8080", "-b", "0.0.0.0"]
4 changes: 4 additions & 0 deletions frameworks/rage/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
source 'https://rubygems.org'

gem "rage-rb", "~> 1.19"
gem 'sqlite3', '~> 2.6'
119 changes: 119 additions & 0 deletions frameworks/rage/app/controllers/benchmark_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# frozen_string_literal: true

require 'zlib'

class BenchmarkController < RageController::API
# Pre-load datasets at class level (shared across workers via preload)
DATASET_PATH = ENV.fetch('DATASET_PATH', '/data/dataset.json')
LARGE_DATASET_PATH = '/data/dataset-large.json'

@db_available = File.exist?('/data/benchmark.db')

if File.exist?(DATASET_PATH)
@dataset_items = JSON.parse(File.read(DATASET_PATH))
end

if File.exist?(LARGE_DATASET_PATH)
raw = JSON.parse(File.read(LARGE_DATASET_PATH))
items = raw.map { |d| d.merge('total' => (d['price'] * d['quantity'] * 100).round / 100.0) }
@large_json_payload = JSON.generate({ 'items' => items, 'count' => items.length })
end

DB_QUERY = 'SELECT id, name, category, price, quantity, active, tags, rating_score, rating_count FROM items WHERE price BETWEEN ? AND ? LIMIT 50'

def self.db_available = @db_available
def self.large_json_payload = @large_json_payload
def self.dataset_items = @dataset_items

before_action do
headers["server"] = "rage"
end

def pipeline
render plain: 'ok'
end

def baseline_one
total = 0
params.each_value do |v|
total += v.to_i
end
if request.post?
body_str = request.send(:rack_request).body.read.to_s.strip
total += body_str.to_i
end
render plain: total.to_s
end

def baseline_two
total = 0
params.each_value do |v|
total += v.to_i
end
render plain: total.to_s
end

def json_endpoint
if self.class.dataset_items
items = self.class.dataset_items.map { |d| d.merge('total' => (d['price'] * d['quantity'] * 100).round / 100.0) }
render json: { 'items' => items, 'count' => items.length }
else
head 500
end
end

def compression
if self.class.large_json_payload
sio = StringIO.new
gz = Zlib::GzipWriter.new(sio, 1)
gz.write(self.class.large_json_payload)
gz.close
response.headers['Content-Type'] = 'application/json'
response.headers['Content-Encoding'] = 'gzip'
render plain: sio.string
else
head 500
end
end

def db
unless self.class.db_available
render json: { items: [], count: 0 }
return
end

min_val = (params[:min] || 10).to_f
max_val = (params[:max] || 50).to_f
conn = get_db
rows = conn.execute(DB_QUERY, [min_val, max_val])
items = rows.map do |r|
{
'id' => r['id'], 'name' => r['name'], 'category' => r['category'],
'price' => r['price'], 'quantity' => r['quantity'], 'active' => r['active'] == 1,
'tags' => JSON.parse(r['tags']),
'rating' => { 'score' => r['rating_score'], 'count' => r['rating_count'] }
}
end
render json: { items: items, count: items.length }
end

def upload
data = request.send(:rack_request).body.read
render plain: data.bytesize.to_s
end

def not_found
head 404
end

private

def get_db
Fiber.current[:rage_db] ||= begin
db = SQLite3::Database.new('/data/benchmark.db', readonly: true)
db.execute('PRAGMA mmap_size=268435456')
db.results_as_hash = true
db
end
end
end
2 changes: 2 additions & 0 deletions frameworks/rage/config.ru
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
require_relative 'config/application'
run Rage.application
12 changes: 12 additions & 0 deletions frameworks/rage/config/application.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

require 'bundler/setup'
Bundler.require(:default)

require 'rage/all'

Rage.configure do
# use this to add settings that are constant across all environments
end

require "rage/setup"
4 changes: 4 additions & 0 deletions frameworks/rage/config/environments/development.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Rage.configure do
config.server.workers_count = -1
config.logger = Rage::Logger.new(STDOUT)
end
3 changes: 3 additions & 0 deletions frameworks/rage/config/environments/production.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Rage.configure do
config.logger = Rage::Logger.new(STDOUT)
end
13 changes: 13 additions & 0 deletions frameworks/rage/config/routes.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Rage.routes.draw do
get '/pipeline', to: 'benchmark#pipeline'
get '/baseline11', to: 'benchmark#baseline_one'
post '/baseline11', to: 'benchmark#baseline_one'
get '/baseline2', to: 'benchmark#baseline_two'
get '/json', to: 'benchmark#json_endpoint'
get '/compression', to: 'benchmark#compression'
get '/db', to: 'benchmark#db'
post '/upload', to: 'benchmark#upload'

# Catch-all for unknown paths → 404
get '*', to: 'benchmark#not_found'
end
19 changes: 19 additions & 0 deletions frameworks/rage/meta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"display_name": "Rage",
"language": "Ruby",
"type": "framework",
"engine": "iodine",
"description": "Rage is a modern Ruby framework designed for non-blocking I/O and simpler infrastructure",
"repo": "https://github.com/rage-rb/rage",
"enabled": true,
"tests": [
"baseline",
"pipelined",
"noisy",
"limited-conn",
"json",
"upload",
"compression",
"mixed"
]
}
Loading