From b0e5daf53584f7f4d3f1c7369265fed274067b61 Mon Sep 17 00:00:00 2001 From: Roman Samoilov Date: Wed, 17 Apr 2024 18:27:09 +0100 Subject: [PATCH] [Ruby] Add rage-rb --- frameworks/Ruby/rage/Gemfile | 13 ++++ frameworks/Ruby/rage/README.md | 45 +++++++++++ frameworks/Ruby/rage/Rakefile | 1 + .../app/controllers/application_controller.rb | 2 + .../app/controllers/benchmarks_controller.rb | 77 +++++++++++++++++++ .../rage/app/models/application_record.rb | 3 + frameworks/Ruby/rage/app/models/fortune.rb | 7 ++ frameworks/Ruby/rage/app/models/world.rb | 9 +++ .../Ruby/rage/app/views/fortunes.html.erb | 12 +++ frameworks/Ruby/rage/benchmark_config.json | 30 ++++++++ frameworks/Ruby/rage/config.ru | 4 + frameworks/Ruby/rage/config/application.rb | 14 ++++ .../rage/config/environments/development.rb | 4 + .../rage/config/environments/production.rb | 3 + .../rage/config/initializers/activerecord.rb | 17 ++++ frameworks/Ruby/rage/config/routes.rb | 10 +++ frameworks/Ruby/rage/lib/.keep | 0 frameworks/Ruby/rage/rage.dockerfile | 14 ++++ 18 files changed, 265 insertions(+) create mode 100644 frameworks/Ruby/rage/Gemfile create mode 100755 frameworks/Ruby/rage/README.md create mode 100644 frameworks/Ruby/rage/Rakefile create mode 100644 frameworks/Ruby/rage/app/controllers/application_controller.rb create mode 100644 frameworks/Ruby/rage/app/controllers/benchmarks_controller.rb create mode 100644 frameworks/Ruby/rage/app/models/application_record.rb create mode 100644 frameworks/Ruby/rage/app/models/fortune.rb create mode 100644 frameworks/Ruby/rage/app/models/world.rb create mode 100644 frameworks/Ruby/rage/app/views/fortunes.html.erb create mode 100755 frameworks/Ruby/rage/benchmark_config.json create mode 100644 frameworks/Ruby/rage/config.ru create mode 100644 frameworks/Ruby/rage/config/application.rb create mode 100644 frameworks/Ruby/rage/config/environments/development.rb create mode 100644 frameworks/Ruby/rage/config/environments/production.rb create mode 100644 frameworks/Ruby/rage/config/initializers/activerecord.rb create mode 100644 frameworks/Ruby/rage/config/routes.rb create mode 100644 frameworks/Ruby/rage/lib/.keep create mode 100644 frameworks/Ruby/rage/rage.dockerfile diff --git a/frameworks/Ruby/rage/Gemfile b/frameworks/Ruby/rage/Gemfile new file mode 100644 index 000000000000..a7f090d01f9d --- /dev/null +++ b/frameworks/Ruby/rage/Gemfile @@ -0,0 +1,13 @@ +source "https://rubygems.org" + +gem "rage-rb", "~> 1.3" + +gem "pg", "~> 1.0" +gem "activerecord", "~> 7.0.0", require: "active_record" + +# Build JSON APIs with ease +# gem "alba" + +# Get 50% to 150% boost when parsing JSON. +# Rage will automatically use FastJsonparser if it is available. +# gem "fast_jsonparser" diff --git a/frameworks/Ruby/rage/README.md b/frameworks/Ruby/rage/README.md new file mode 100755 index 000000000000..912ef97d2ff1 --- /dev/null +++ b/frameworks/Ruby/rage/README.md @@ -0,0 +1,45 @@ +# Rage Benchmarking Test + +https://github.com/rage-rb/rage + +### Test Type Implementation Source Code + +* [JSON](app/controllers/benchmarks_controller.rb) +* [PLAINTEXT](app/controllers/benchmarks_controller.rb) +* [DB](app/controllers/benchmarks_controller.rb) +* [QUERY](app/controllers/benchmarks_controller.rb) +* [UPDATE](app/controllers/benchmarks_controller.rb) +* [FORTUNES](app/controllers/benchmarks_controller.rb) + +## Important Libraries + +The tests were run with: + +* [ActiveRecord](https://rubygems.org/gems/activerecord) +* [PG](https://rubygems.org/gems/pg) + +## Test URLs + +### JSON + +http://localhost:8080/json + +### PLAINTEXT + +http://localhost:8080/plaintext + +### DB + +http://localhost:8080/db + +### QUERY + +http://localhost:8080/queries?queries= + +### UPDATE + +http://localhost:8080/updates?queries= + +### FORTUNES + +http://localhost:8080/fortunes diff --git a/frameworks/Ruby/rage/Rakefile b/frameworks/Ruby/rage/Rakefile new file mode 100644 index 000000000000..046f1fcbd8d8 --- /dev/null +++ b/frameworks/Ruby/rage/Rakefile @@ -0,0 +1 @@ +require_relative "config/application" diff --git a/frameworks/Ruby/rage/app/controllers/application_controller.rb b/frameworks/Ruby/rage/app/controllers/application_controller.rb new file mode 100644 index 000000000000..c3238c523921 --- /dev/null +++ b/frameworks/Ruby/rage/app/controllers/application_controller.rb @@ -0,0 +1,2 @@ +class ApplicationController < RageController::API +end diff --git a/frameworks/Ruby/rage/app/controllers/benchmarks_controller.rb b/frameworks/Ruby/rage/app/controllers/benchmarks_controller.rb new file mode 100644 index 000000000000..884356e58c10 --- /dev/null +++ b/frameworks/Ruby/rage/app/controllers/benchmarks_controller.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true + +class BenchmarksController < ApplicationController + ALL_DB_IDS = (1..10_000).to_a + FORTUNES_TEMPLATE = ERB.new(Rage.root.join("app/views/fortunes.html.erb").read) + + before_action do + headers["server"] = "rage" + end + + def json + render json: { message: "Hello, World!" } + end + + def plaintext + render plain: "Hello, World!" + end + + def db + render json: World.find(random_id) + end + + def queries + records = requested_ids.map do |id| + World.find(id) + end + + render json: records + end + + def fortunes + records = Fortune.pluck(:id, :message).map! { |id, message| { id:, message: } } + + records << Fortune.new(id: 0, message: "Additional fortune added at request time.") + records.sort_by! { |record| record[:message] } + + render plain: FORTUNES_TEMPLATE.result(binding) + headers["content-type"] = "text/html; charset=utf-8" + end + + def updates + records = requested_ids.map do |id| + World.find(id) + end + + updates = records.map do |record| + new_value = random_id + new_value = random_id until new_value != record.randomNumber + + record.randomNumber = new_value + + { id: record.id, randomnumber: new_value } + end + + World.upsert_all(updates.sort_by! { |u| u[:id] }) + + render json: records + end + + private + + def requested_ids + num = params[:queries].to_i + + if num > 500 + num = 500 + elsif num < 1 + num = 1 + end + + ALL_DB_IDS.sample(num) + end + + def random_id + Random.rand(9_999) + 1 + end +end diff --git a/frameworks/Ruby/rage/app/models/application_record.rb b/frameworks/Ruby/rage/app/models/application_record.rb new file mode 100644 index 000000000000..b63caeb8a5c4 --- /dev/null +++ b/frameworks/Ruby/rage/app/models/application_record.rb @@ -0,0 +1,3 @@ +class ApplicationRecord < ActiveRecord::Base + primary_abstract_class +end diff --git a/frameworks/Ruby/rage/app/models/fortune.rb b/frameworks/Ruby/rage/app/models/fortune.rb new file mode 100644 index 000000000000..6b7ad122f802 --- /dev/null +++ b/frameworks/Ruby/rage/app/models/fortune.rb @@ -0,0 +1,7 @@ +class Fortune < ApplicationRecord + self.table_name = "Fortune" + + def as_json(*) + attributes + end +end diff --git a/frameworks/Ruby/rage/app/models/world.rb b/frameworks/Ruby/rage/app/models/world.rb new file mode 100644 index 000000000000..951aab55b640 --- /dev/null +++ b/frameworks/Ruby/rage/app/models/world.rb @@ -0,0 +1,9 @@ +class World < ApplicationRecord + self.table_name = "World" + + def as_json(*) + attributes + end + + alias_attribute(:randomNumber, :randomnumber) +end diff --git a/frameworks/Ruby/rage/app/views/fortunes.html.erb b/frameworks/Ruby/rage/app/views/fortunes.html.erb new file mode 100644 index 000000000000..1aa63f3772ac --- /dev/null +++ b/frameworks/Ruby/rage/app/views/fortunes.html.erb @@ -0,0 +1,12 @@ + + + Fortunes + + + + <% records.each do |record| %> + + <% end %> +
idmessage
<%= record[:id] %><%= CGI.escape_html(record[:message]) %>
+ + diff --git a/frameworks/Ruby/rage/benchmark_config.json b/frameworks/Ruby/rage/benchmark_config.json new file mode 100755 index 000000000000..04d51d3ca3b8 --- /dev/null +++ b/frameworks/Ruby/rage/benchmark_config.json @@ -0,0 +1,30 @@ +{ + "framework": "rage", + "tests": [ + { + "default": { + "json_url": "/json", + "plaintext_url": "/plaintext", + "db_url": "/db", + "query_url": "/queries?queries=", + "fortune_url": "/fortunes", + "update_url": "/updates?queries=", + "port": 8080, + "approach": "Realistic", + "classification": "Micro", + "database": "postgres", + "framework": "Rage", + "language": "Ruby", + "flavor": "None", + "orm": "Full", + "platform": "Rack", + "webserver": "Rage-Iodine", + "os": "Linux", + "database_os": "Linux", + "display_name": "Rage", + "notes": "", + "versus": "None" + } + } + ] +} diff --git a/frameworks/Ruby/rage/config.ru b/frameworks/Ruby/rage/config.ru new file mode 100644 index 000000000000..52de8a404791 --- /dev/null +++ b/frameworks/Ruby/rage/config.ru @@ -0,0 +1,4 @@ +require_relative "config/application" + +run Rage.application +Rage.load_middlewares(self) diff --git a/frameworks/Ruby/rage/config/application.rb b/frameworks/Ruby/rage/config/application.rb new file mode 100644 index 000000000000..9af142340b3f --- /dev/null +++ b/frameworks/Ruby/rage/config/application.rb @@ -0,0 +1,14 @@ +require "bundler/setup" +require "rage" +Bundler.require(*Rage.groups) + +require "rage/all" + +Rage.configure do + # use this to add settings that are constant across all environments +end + +require "erb" +require "cgi" + +require "rage/setup" diff --git a/frameworks/Ruby/rage/config/environments/development.rb b/frameworks/Ruby/rage/config/environments/development.rb new file mode 100644 index 000000000000..ba6e1d01423b --- /dev/null +++ b/frameworks/Ruby/rage/config/environments/development.rb @@ -0,0 +1,4 @@ +Rage.configure do + config.server.workers_count = -1 + config.logger = ActiveRecord::Base.logger = Rage::Logger.new(STDOUT) +end diff --git a/frameworks/Ruby/rage/config/environments/production.rb b/frameworks/Ruby/rage/config/environments/production.rb new file mode 100644 index 000000000000..0189c7742fa7 --- /dev/null +++ b/frameworks/Ruby/rage/config/environments/production.rb @@ -0,0 +1,3 @@ +Rage.configure do + config.logger = nil +end diff --git a/frameworks/Ruby/rage/config/initializers/activerecord.rb b/frameworks/Ruby/rage/config/initializers/activerecord.rb new file mode 100644 index 000000000000..c0e3eb08d44c --- /dev/null +++ b/frameworks/Ruby/rage/config/initializers/activerecord.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require "etc" + +connection = { + adapter: "postgresql", + host: "tfb-database", + username: "benchmarkdbuser", + password: "benchmarkdbpass", + database: "hello_world", + reaping_frequency: 0, + pool: (2 * Math.log(256 / Etc.nprocessors)).floor +} + +puts "ActiveRecord connection options: #{connection.inspect}" + +ActiveRecord::Base.establish_connection(connection) diff --git a/frameworks/Ruby/rage/config/routes.rb b/frameworks/Ruby/rage/config/routes.rb new file mode 100644 index 000000000000..98def92a7e74 --- /dev/null +++ b/frameworks/Ruby/rage/config/routes.rb @@ -0,0 +1,10 @@ +Rage.routes.draw do + root to: ->(env) { [200, {}, "It works!"] } + + get "json", to: "benchmarks#json" + get "plaintext", to: "benchmarks#plaintext" + get "db", to: "benchmarks#db" + get "queries", to: "benchmarks#queries" + get "fortunes", to: "benchmarks#fortunes" + get "updates", to: "benchmarks#updates" +end diff --git a/frameworks/Ruby/rage/lib/.keep b/frameworks/Ruby/rage/lib/.keep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/frameworks/Ruby/rage/rage.dockerfile b/frameworks/Ruby/rage/rage.dockerfile new file mode 100644 index 000000000000..a1e80a095f3a --- /dev/null +++ b/frameworks/Ruby/rage/rage.dockerfile @@ -0,0 +1,14 @@ +FROM ruby:3.3 + +EXPOSE 8080 +WORKDIR /rage + +COPY Gemfile* /rage/ +RUN bundle install --jobs=8 +COPY . /rage + +ENV RUBY_YJIT_ENABLE=1 +ENV RAGE_PATCH_AR_POOL=1 +ENV BUNDLE_FORCE_RUBY_PLATFORM=true + +CMD bundle exec rage s -b 0.0.0.0 -p 8080 -e production