Browse Source

Roda (#8160)

* added devcontainer

* upgraded to ruby 3.2 and the latest versions of all the gems. Also switched out the json gem for OJ

* WIP

* finished upgrading ruby version and gems. Also enabled YJIT

* removed the devcontainer
Tim Uckun 2 years ago
parent
commit
7b909687e4

+ 1 - 0
.gitignore

@@ -57,6 +57,7 @@ benchmark.cfg
 
 # Visual Studio Code
 .vscode
+.history
 
 # vim
 .*.sw[a-p]

+ 3 - 0
frameworks/Ruby/roda-sequel/.gitignore

@@ -0,0 +1,3 @@
+.history
+.devcontainer
+tmp

+ 12 - 12
frameworks/Ruby/roda-sequel/Gemfile

@@ -1,19 +1,19 @@
-source 'https://rubygems.org'
+source "https://rubygems.org"
 
-gem 'erubi', '~> 1.10'
-gem 'json', '~> 2.5'
-gem 'passenger', '~> 6.0', :platforms=>[:ruby, :mswin], :require=>false
-gem 'puma', '~> 5.2', :require=>false
-gem 'sequel', '~> 5.44'
-gem 'roda', '~> 3.43'
-gem 'tilt', '~> 2.0', :require=>'tilt/erb'
-gem 'unicorn', '~> 6.0', :platforms=>[:ruby, :mswin], :require=>false
+gem "erubi", "~> 1.12"
+gem "passenger", "~> 6.0", platforms: %i[ruby mswin], require: false
+gem "puma", "~> 6.2", require: false
+gem "sequel", "~> 5.67"
+gem "roda", "~> 3.66"
+gem "tilt", "~> 2.1", require: "tilt/erb"
+gem "unicorn", "~> 6.1", platforms: %i[ruby mswin], require: false
+gem "oj", "~> 3.14"
 
 group :mysql do
-  gem 'mysql2', '~> 0.5', :platforms=>[:ruby, :mswin]
+  gem "mysql2", "~> 0.5", platforms: %i[ruby mswin]
 end
 
 group :postgresql do
-  gem 'pg', '~> 1.2', :platforms=>[:ruby, :mswin]
-  gem 'sequel_pg', '~> 1.14', :platforms=>:ruby, :require=>false
+  gem "pg", "~> 1.4", platforms: %i[ruby mswin]
+  gem "sequel_pg", "~> 1.17", platforms: :ruby, require: false
 end

+ 0 - 46
frameworks/Ruby/roda-sequel/Gemfile.lock

@@ -1,46 +0,0 @@
-GEM
-  remote: https://rubygems.org/
-  specs:
-    erubi (1.10.0)
-    json (2.5.1)
-    kgio (2.11.3)
-    mysql2 (0.5.3)
-    nio4r (2.5.7)
-    passenger (6.0.8)
-      rack
-      rake (>= 0.8.1)
-    pg (1.2.3)
-    puma (5.2.2)
-      nio4r (~> 2.0)
-    rack (2.2.3)
-    raindrops (0.19.1)
-    rake (13.0.3)
-    roda (3.43.1)
-      rack
-    sequel (5.44.0)
-    sequel_pg (1.14.0)
-      pg (>= 0.18.0, != 1.2.0)
-      sequel (>= 4.38.0)
-    tilt (2.0.10)
-    unicorn (6.0.0)
-      kgio (~> 2.6)
-      raindrops (~> 0.7)
-
-PLATFORMS
-  x86_64-linux
-
-DEPENDENCIES
-  erubi (~> 1.10)
-  json (~> 2.5)
-  mysql2 (~> 0.5)
-  passenger (~> 6.0)
-  pg (~> 1.2)
-  puma (~> 5.2)
-  roda (~> 3.43)
-  sequel (~> 5.44)
-  sequel_pg (~> 1.14)
-  tilt (~> 2.0)
-  unicorn (~> 6.0)
-
-BUNDLED WITH
-   2.2.16

+ 36 - 20
frameworks/Ruby/roda-sequel/boot.rb

@@ -1,22 +1,25 @@
 # frozen_string_literal: true
-require 'bundler/setup'
-require 'time'
-
+require "bundler/setup"
+require "time"
+require "oj"
 MAX_PK = 10_000
 QUERIES_MIN = 1
 QUERIES_MAX = 500
 SEQUEL_NO_ASSOCIATIONS = true
 
+# Use the OJ gem instead of the JSON one
+Oj.mimic_JSON()
+
 SERVER_STRING =
   if defined?(PhusionPassenger)
     [
       PhusionPassenger::SharedConstants::SERVER_TOKEN_NAME,
       PhusionPassenger::VERSION_STRING
-    ].join('/').freeze
+    ].join("/").freeze
   elsif defined?(Puma)
     Puma::Const::PUMA_SERVER_STRING
   elsif defined?(Unicorn)
-    Unicorn::HttpParser::DEFAULTS['SERVER_SOFTWARE']
+    Unicorn::HttpParser::DEFAULTS["SERVER_SOFTWARE"]
   end
 
 Bundler.require(:default) # Load core modules
@@ -25,41 +28,54 @@ def connect(dbtype)
   Bundler.require(dbtype) # Load database-specific modules
 
   adapters = {
-    :mysql=>{ :jruby=>'jdbc:mysql', :mri=>'mysql2' },
-    :postgresql=>{ :jruby=>'jdbc:postgresql', :mri=>'postgres' }
+    mysql: {
+      jruby: "jdbc:mysql",
+      mri: "mysql2"
+    },
+    postgresql: {
+      jruby: "jdbc:postgresql",
+      mri: "postgres"
+    }
   }
 
   opts = {}
 
   # Determine threading/thread pool size and timeout
   if defined?(JRUBY_VERSION)
-    opts[:max_connections] = (2 * Math.log(Integer(ENV.fetch('MAX_CONCURRENCY')))).floor
+    opts[:max_connections] = (
+      2 * Math.log(Integer(ENV.fetch("MAX_CONCURRENCY")))
+    ).floor
     opts[:pool_timeout] = 10
-  elsif defined?(Puma) && (threads = Puma.cli_config.options.fetch(:max_threads)) > 1
+  elsif defined?(Puma) &&
+        (threads = Puma.cli_config.options.fetch(:max_threads)) > 1
     opts[:max_connections] = (2 * Math.log(threads)).floor
     opts[:pool_timeout] = 10
   else
     Sequel.single_threaded = true
   end
 
-  Sequel.connect \
-    '%{adapter}://%{host}/%{database}?user=%{user}&password=%{password}' % {
-      :adapter=>adapters.fetch(dbtype).fetch(defined?(JRUBY_VERSION) ? :jruby : :mri),
-      :host=>'tfb-database',
-      :database=>'hello_world',
-      :user=>'benchmarkdbuser',
-      :password=>'benchmarkdbpass'
-    }, opts
+  Sequel.connect "%{adapter}://%{host}/%{database}?user=%{user}&password=%{password}" %
+                   {
+                     adapter:
+                       adapters.fetch(dbtype).fetch(
+                         defined?(JRUBY_VERSION) ? :jruby : :mri
+                       ),
+                     host: "tfb-database",
+                     database: "hello_world",
+                     user: "benchmarkdbuser",
+                     password: "benchmarkdbpass"
+                   },
+                 opts
 end
 
-DB = connect ENV.fetch('DBTYPE').to_sym
+DB = connect ENV.fetch("DBTYPE").to_sym
 
 # Define ORM models
-class World < Sequel::Model(:World)
+class World < Sequel.Model(:World)
   def_column_alias(:randomnumber, :randomNumber) if DB.database_type == :mysql
 end
 
-class Fortune < Sequel::Model(:Fortune)
+class Fortune < Sequel.Model(:Fortune)
   # Allow setting id to zero (0) per benchmark requirements
   unrestrict_primary_key
 end

+ 51 - 64
frameworks/Ruby/roda-sequel/hello_world.rb

@@ -3,14 +3,12 @@
 # Our Rack application to be executed by rackup
 class HelloWorld < Roda
   plugin :hooks
-  plugin :render, escape: true, layout_opts: { cache_key: 'default_layout' }
-  plugin :static_routing
+  plugin :render, escape: true, layout_opts: { cache_key: "default_layout" }
 
   def bounded_queries
-    queries = request['queries'].to_i
+    queries = request.params["queries"].to_i
     return QUERIES_MIN if queries < QUERIES_MIN
     return QUERIES_MAX if queries > QUERIES_MAX
-
     queries
   end
 
@@ -19,73 +17,62 @@ class HelloWorld < Roda
     rand(MAX_PK) + 1
   end
 
-  after do
-    response['Date'] = Time.now.httpdate
-    response['Server'] = SERVER_STRING if SERVER_STRING
-  end
-
-  # Test type 1: JSON serialization
-  static_get '/json' do |_|
-    response['Content-Type'] = 'application/json'
-
-    { message: 'Hello, World!' }.to_json
-  end
+  route do |r|
+    response["Date"] = Time.now.httpdate
+    response["Server"] = SERVER_STRING if SERVER_STRING
+    #default content type
+    response["Content-Type"] = "application/json"
 
-  # Test type 2: Single database query
-  static_get '/db' do |_|
-    response['Content-Type'] = 'application/json'
-
-    World.with_pk(rand1).values.to_json
-  end
-
-  # Test type 3: Multiple database queries
-  static_get '/queries' do |_|
-    response['Content-Type'] = 'application/json'
-    worlds = DB.synchronize do
-      Array.new(bounded_queries) do
-        World.with_pk(rand1).values
-      end
+    # Test type 1: JSON serialization
+    r.is "json" do
+      { message: "Hello, World!" }.to_json
     end
 
-    worlds.to_json
-  end
-
-  # Test type 4: Fortunes
-  static_get '/fortunes' do |_|
-    response['Content-Type'] = 'text/html; charset=utf-8'
-    @fortunes = Fortune.all
-    @fortunes << Fortune.new(
-      id: 0,
-      message: 'Additional fortune added at request time.'
-    )
-    @fortunes.sort_by!(&:message)
-
-    view :fortunes
-  end
+    # Test type 2: Single database query
+    r.is "db" do
+      World.with_pk(rand1).values.to_json
+    end
 
-  # Test type 5: Database updates
-  static_get '/updates' do |_|
-    response['Content-Type'] = 'application/json'
-    worlds = DB.synchronize do
-      Array.new(bounded_queries) do
-        world = World.with_pk(rand1)
-        new_value = rand1
-        new_value = rand1 while new_value == world.randomnumber
-        world.update(randomnumber: new_value)
-        world.values
-      end
+    # Test type 3: Multiple database queries
+    r.is "queries" do
+      worlds =
+        DB.synchronize do
+          Array.new(bounded_queries) { World.with_pk(rand1).values }
+        end
+      worlds.to_json
     end
 
-    worlds.to_json
-  end
+    # Test type 4: Fortunes
+    r.is "fortunes" do
+      response["Content-Type"] = "text/html; charset=utf-8"
+      @fortunes = Fortune.all
+      @fortunes << Fortune.new(
+        id: 0,
+        message: "Additional fortune added at request time."
+      )
+      @fortunes.sort_by!(&:message)
+      view :fortunes
+    end
 
-  # Test type 6: Plaintext
-  static_get '/plaintext' do |_|
-    response['Content-Type'] = 'text/plain'
+    # Test type 5: Database updates
+    r.is "updates" do
+      worlds =
+        DB.synchronize do
+          Array.new(bounded_queries) do
+            world = World.with_pk(rand1)
+            new_value = rand1
+            new_value = rand1 while new_value == world.randomnumber
+            world.update(randomnumber: new_value)
+            world.values
+          end
+        end
+      worlds.to_json
+    end
 
-    'Hello, World!'
+    # Test type 6: Plaintext
+    r.is "plaintext" do
+      response["Content-Type"] = "text/plain"
+      "Hello, World!"
+    end
   end
-
-  # Even though we don't have any non-static routes, this is still required.
-  route { |_| }
 end

+ 5 - 2
frameworks/Ruby/roda-sequel/roda-sequel-passenger-mri.dockerfile

@@ -1,9 +1,12 @@
-FROM ruby:2.7
+FROM ruby:3.2
 
 ADD ./ /roda-sequel
 WORKDIR /roda-sequel
 
-RUN bundle install --jobs=4 --gemfile=/roda-sequel/Gemfile --path=/roda-sequel/roda-sequel/bundle
+ENV BUNDLE_FORCE_RUBY_PLATFORM=true
+ENV RUBY_YJIT_ENABLE=1
+
+RUN bundle install --jobs=8
 
 # TODO: https://github.com/phusion/passenger/issues/1916
 ENV _PASSENGER_FORCE_HTTP_SESSION=true

+ 5 - 2
frameworks/Ruby/roda-sequel/roda-sequel-postgres-passenger-mri.dockerfile

@@ -1,9 +1,12 @@
-FROM ruby:2.7
+FROM ruby:3.2
 
 ADD ./ /roda-sequel
 WORKDIR /roda-sequel
 
-RUN bundle install --jobs=4 --gemfile=/roda-sequel/Gemfile --path=/roda-sequel/roda-sequel/bundle
+ENV BUNDLE_FORCE_RUBY_PLATFORM=true
+ENV RUBY_YJIT_ENABLE=1
+
+RUN bundle install --jobs=8
 
 # TODO: https://github.com/phusion/passenger/issues/1916
 ENV _PASSENGER_FORCE_HTTP_SESSION=true

+ 5 - 2
frameworks/Ruby/roda-sequel/roda-sequel-postgres-unicorn-mri.dockerfile

@@ -1,9 +1,12 @@
-FROM ruby:2.7
+FROM ruby:3.2
 
 ADD ./ /roda-sequel
 WORKDIR /roda-sequel
 
-RUN bundle install --jobs=4 --gemfile=/roda-sequel/Gemfile --path=/roda-sequel/roda-sequel/bundle
+ENV BUNDLE_FORCE_RUBY_PLATFORM=true
+ENV RUBY_YJIT_ENABLE=1
+
+RUN bundle install --jobs=8
 
 ENV DBTYPE=postgresql
 

+ 5 - 2
frameworks/Ruby/roda-sequel/roda-sequel-postgres.dockerfile

@@ -1,9 +1,12 @@
-FROM ruby:2.7
+FROM ruby:3.2
 
 ADD ./ /roda-sequel
 WORKDIR /roda-sequel
 
-RUN bundle install --jobs=4 --gemfile=/roda-sequel/Gemfile --path=/roda-sequel/roda-sequel/bundle
+ENV BUNDLE_FORCE_RUBY_PLATFORM=true
+ENV RUBY_YJIT_ENABLE=1
+
+RUN bundle install --jobs=8
 
 ENV DBTYPE=postgresql
 

+ 5 - 2
frameworks/Ruby/roda-sequel/roda-sequel-unicorn-mri.dockerfile

@@ -1,9 +1,12 @@
-FROM ruby:2.7
+FROM ruby:3.2
 
 ADD ./ /roda-sequel
 WORKDIR /roda-sequel
 
-RUN bundle install --jobs=4 --gemfile=/roda-sequel/Gemfile --path=/roda-sequel/roda-sequel/bundle
+ENV BUNDLE_FORCE_RUBY_PLATFORM=true
+ENV RUBY_YJIT_ENABLE=1
+
+RUN bundle install --jobs=8
 
 ENV DBTYPE=mysql
 

+ 5 - 2
frameworks/Ruby/roda-sequel/roda-sequel.dockerfile

@@ -1,9 +1,12 @@
-FROM ruby:2.7
+FROM ruby:3.2
 
 ADD ./ /roda-sequel
 WORKDIR /roda-sequel
 
-RUN bundle install --jobs=4 --gemfile=/roda-sequel/Gemfile --path=/roda-sequel/roda-sequel/bundle
+ENV BUNDLE_FORCE_RUBY_PLATFORM=true
+ENV RUBY_YJIT_ENABLE=1
+
+RUN bundle install --jobs=8
 
 ENV DBTYPE=mysql