From fb6834a55b92ed740d54051e47317cc741e830b2 Mon Sep 17 00:00:00 2001 From: Roman Samoilov <2270393+rsamoilov@users.noreply.github.com> Date: Wed, 15 Jan 2025 19:54:17 +0000 Subject: [PATCH] Add rage-sequel --- frameworks/Ruby/rage-sequel/Gemfile | 7 ++ frameworks/Ruby/rage-sequel/Gemfile.lock | 37 +++++++++ frameworks/Ruby/rage-sequel/README.md | 47 +++++++++++ frameworks/Ruby/rage-sequel/Rakefile | 1 + .../app/controllers/application_controller.rb | 2 + .../app/controllers/benchmarks_controller.rb | 79 +++++++++++++++++++ .../rage-sequel/app/views/fortunes.html.erb | 12 +++ .../Ruby/rage-sequel/benchmark_config.json | 30 +++++++ frameworks/Ruby/rage-sequel/config.ru | 3 + .../Ruby/rage-sequel/config/application.rb | 14 ++++ .../config/environments/development.rb | 4 + .../config/environments/production.rb | 3 + .../rage-sequel/config/initializers/sequel.rb | 43 ++++++++++ frameworks/Ruby/rage-sequel/config/routes.rb | 10 +++ frameworks/Ruby/rage-sequel/lib/.keep | 0 .../Ruby/rage-sequel/rage-sequel.dockerfile | 13 +++ 16 files changed, 305 insertions(+) create mode 100644 frameworks/Ruby/rage-sequel/Gemfile create mode 100644 frameworks/Ruby/rage-sequel/Gemfile.lock create mode 100755 frameworks/Ruby/rage-sequel/README.md create mode 100644 frameworks/Ruby/rage-sequel/Rakefile create mode 100644 frameworks/Ruby/rage-sequel/app/controllers/application_controller.rb create mode 100644 frameworks/Ruby/rage-sequel/app/controllers/benchmarks_controller.rb create mode 100644 frameworks/Ruby/rage-sequel/app/views/fortunes.html.erb create mode 100755 frameworks/Ruby/rage-sequel/benchmark_config.json create mode 100644 frameworks/Ruby/rage-sequel/config.ru create mode 100644 frameworks/Ruby/rage-sequel/config/application.rb create mode 100644 frameworks/Ruby/rage-sequel/config/environments/development.rb create mode 100644 frameworks/Ruby/rage-sequel/config/environments/production.rb create mode 100644 frameworks/Ruby/rage-sequel/config/initializers/sequel.rb create mode 100644 frameworks/Ruby/rage-sequel/config/routes.rb create mode 100644 frameworks/Ruby/rage-sequel/lib/.keep create mode 100644 frameworks/Ruby/rage-sequel/rage-sequel.dockerfile diff --git a/frameworks/Ruby/rage-sequel/Gemfile b/frameworks/Ruby/rage-sequel/Gemfile new file mode 100644 index 00000000000..4ee2e620f6e --- /dev/null +++ b/frameworks/Ruby/rage-sequel/Gemfile @@ -0,0 +1,7 @@ +source "https://rubygems.org" + +gem "rage-rb", "~> 1.10" + +gem "pg", "~> 1.0" +gem 'sequel', '~> 5.0' +gem 'sequel_pg', '~> 1.6', platforms: :ruby, require: false diff --git a/frameworks/Ruby/rage-sequel/Gemfile.lock b/frameworks/Ruby/rage-sequel/Gemfile.lock new file mode 100644 index 00000000000..d1ad00bb988 --- /dev/null +++ b/frameworks/Ruby/rage-sequel/Gemfile.lock @@ -0,0 +1,37 @@ +GEM + remote: https://rubygems.org/ + specs: + bigdecimal (3.1.9) + pg (1.5.9) + rack (2.2.10) + rack-test (2.2.0) + rack (>= 1.3) + rage-iodine (4.0.0) + rage-rb (1.11.0) + rack (~> 2.0) + rack-test (~> 2.1) + rage-iodine (~> 4.0) + rake (>= 12.0) + thor (~> 1.0) + zeitwerk (~> 2.6) + rake (13.2.1) + sequel (5.88.0) + bigdecimal + sequel_pg (1.17.1) + pg (>= 0.18.0, != 1.2.0) + sequel (>= 4.38.0) + thor (1.3.2) + zeitwerk (2.7.1) + +PLATFORMS + ruby + x86_64-darwin-20 + +DEPENDENCIES + pg (~> 1.0) + rage-rb (~> 1.10) + sequel (~> 5.0) + sequel_pg (~> 1.6) + +BUNDLED WITH + 2.5.6 diff --git a/frameworks/Ruby/rage-sequel/README.md b/frameworks/Ruby/rage-sequel/README.md new file mode 100755 index 00000000000..d299d0834ba --- /dev/null +++ b/frameworks/Ruby/rage-sequel/README.md @@ -0,0 +1,47 @@ +# Rage Benchmarking Test + +Rage is a fast web framework compatible with Rails. It uses an event-driven architecture and implements a lightweight, cooperative concurrency model based on Ruby Fibers. + +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: + +* [Sequel](https://rubygems.org/gems/sequel) +* [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-sequel/Rakefile b/frameworks/Ruby/rage-sequel/Rakefile new file mode 100644 index 00000000000..046f1fcbd8d --- /dev/null +++ b/frameworks/Ruby/rage-sequel/Rakefile @@ -0,0 +1 @@ +require_relative "config/application" diff --git a/frameworks/Ruby/rage-sequel/app/controllers/application_controller.rb b/frameworks/Ruby/rage-sequel/app/controllers/application_controller.rb new file mode 100644 index 00000000000..c3238c52392 --- /dev/null +++ b/frameworks/Ruby/rage-sequel/app/controllers/application_controller.rb @@ -0,0 +1,2 @@ +class ApplicationController < RageController::API +end diff --git a/frameworks/Ruby/rage-sequel/app/controllers/benchmarks_controller.rb b/frameworks/Ruby/rage-sequel/app/controllers/benchmarks_controller.rb new file mode 100644 index 00000000000..b02e2d19416 --- /dev/null +++ b/frameworks/Ruby/rage-sequel/app/controllers/benchmarks_controller.rb @@ -0,0 +1,79 @@ +# 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.with_pk(random_id).values + end + + def queries + worlds = DB.synchronize do + requested_ids.map do |id| + World.with_pk(id) + end + end + + render json: worlds.map!(&:values) + end + + def fortunes + records = Fortune.all + + records << Fortune.new(id: 0, message: "Additional fortune added at request time.") + records.sort_by!(&:message) + + render plain: FORTUNES_TEMPLATE.result(binding) + headers["content-type"] = "text/html; charset=utf-8" + end + + def updates + worlds = nil + + DB.synchronize do + worlds = requested_ids.map do |id| + world = World.with_pk(id) + new_value = random_id + new_value = random_id while new_value == world.randomnumber + world.randomnumber = new_value + + world + end + + World.batch_update(worlds) + end + + render json: worlds.map!(&:values) + 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-sequel/app/views/fortunes.html.erb b/frameworks/Ruby/rage-sequel/app/views/fortunes.html.erb new file mode 100644 index 00000000000..2614ca7a7b2 --- /dev/null +++ b/frameworks/Ruby/rage-sequel/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-sequel/benchmark_config.json b/frameworks/Ruby/rage-sequel/benchmark_config.json new file mode 100755 index 00000000000..e4324c06062 --- /dev/null +++ b/frameworks/Ruby/rage-sequel/benchmark_config.json @@ -0,0 +1,30 @@ +{ + "framework": "rage-sequel", + "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-Sequel", + "notes": "", + "versus": "None" + } + } + ] +} diff --git a/frameworks/Ruby/rage-sequel/config.ru b/frameworks/Ruby/rage-sequel/config.ru new file mode 100644 index 00000000000..049a1ad509d --- /dev/null +++ b/frameworks/Ruby/rage-sequel/config.ru @@ -0,0 +1,3 @@ +require_relative "config/application" + +run Rage.application diff --git a/frameworks/Ruby/rage-sequel/config/application.rb b/frameworks/Ruby/rage-sequel/config/application.rb new file mode 100644 index 00000000000..9af142340b3 --- /dev/null +++ b/frameworks/Ruby/rage-sequel/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-sequel/config/environments/development.rb b/frameworks/Ruby/rage-sequel/config/environments/development.rb new file mode 100644 index 00000000000..35d9e7ae7d6 --- /dev/null +++ b/frameworks/Ruby/rage-sequel/config/environments/development.rb @@ -0,0 +1,4 @@ +Rage.configure do + config.server.workers_count = -1 + config.logger = Rage::Logger.new(STDOUT) +end diff --git a/frameworks/Ruby/rage-sequel/config/environments/production.rb b/frameworks/Ruby/rage-sequel/config/environments/production.rb new file mode 100644 index 00000000000..0189c7742fa --- /dev/null +++ b/frameworks/Ruby/rage-sequel/config/environments/production.rb @@ -0,0 +1,3 @@ +Rage.configure do + config.logger = nil +end diff --git a/frameworks/Ruby/rage-sequel/config/initializers/sequel.rb b/frameworks/Ruby/rage-sequel/config/initializers/sequel.rb new file mode 100644 index 00000000000..1a2e070e9d7 --- /dev/null +++ b/frameworks/Ruby/rage-sequel/config/initializers/sequel.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +require "etc" + +SEQUEL_NO_ASSOCIATIONS = true +Sequel.extension :fiber_concurrency + +# Determine thread pool size and timeout +opts = { + max_connections: (2 * Math.log(256 / Etc.nprocessors)).floor, + pool_timeout: 10 +} + +DB = Sequel.connect \ + '%{adapter}://%{host}/%{database}?user=%{user}&password=%{password}' % { + :adapter=>'postgres', + :host=>'tfb-database', + :database=>'hello_world', + :user=>'benchmarkdbuser', + :password=>'benchmarkdbpass' + }, opts + +# Define ORM models +class World < Sequel::Model(:World) + def self.batch_update(worlds) + ids = [] + sql = String.new("UPDATE world SET randomnumber = CASE id ") + worlds.each do |world| + sql << "when #{world.id} then #{world.randomnumber} " + ids << world.id + end + sql << "ELSE randomnumber END WHERE id IN ( #{ids.join(',')})" + DB.run(sql) + end +end + +class Fortune < Sequel::Model(:Fortune) + # Allow setting id to zero (0) per benchmark requirements + unrestrict_primary_key +end + +[World, Fortune].each(&:freeze) +DB.freeze diff --git a/frameworks/Ruby/rage-sequel/config/routes.rb b/frameworks/Ruby/rage-sequel/config/routes.rb new file mode 100644 index 00000000000..98def92a7e7 --- /dev/null +++ b/frameworks/Ruby/rage-sequel/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-sequel/lib/.keep b/frameworks/Ruby/rage-sequel/lib/.keep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/frameworks/Ruby/rage-sequel/rage-sequel.dockerfile b/frameworks/Ruby/rage-sequel/rage-sequel.dockerfile new file mode 100644 index 00000000000..096b256fe18 --- /dev/null +++ b/frameworks/Ruby/rage-sequel/rage-sequel.dockerfile @@ -0,0 +1,13 @@ +FROM ruby:3.4 + +EXPOSE 8080 +WORKDIR /rage-sequel + +COPY Gemfile* /rage-sequel/ +RUN bundle install --jobs=8 +COPY . /rage-sequel + +ENV RUBY_YJIT_ENABLE=1 +ENV BUNDLE_FORCE_RUBY_PLATFORM=true + +CMD bundle exec rage s -b 0.0.0.0 -p 8080 -e production