Bladeren bron

Rails tweaks (#6463)

* move common code out to a function

* update_columns is more commonly used

* update gems and add redis

* set up redis in container for caching

* move cached_query

* update readme

* add rails gitignores

* ignore pyc files in toolset dir

* use bash

* clean up app controller

* be noisy if redis is down

* simplify update and cached query

* update mysql dockerfile

* oops, set mysql as rails env

* remove rails gitignore as this lives in a docker container
Michael Spiz 4 jaren geleden
bovenliggende
commit
26ab4804f9

+ 4 - 3
frameworks/Ruby/rails/Gemfile

@@ -1,9 +1,10 @@
 source 'https://rubygems.org' do
   gem 'listen', '~> 3.3', group: :development
   gem 'mysql2', '0.5.3', group: :mysql
-  gem 'oj', '3.11.2'
+  gem 'oj', '~> 3.11.2'
   gem 'pg', '1.2.3', group: :postgresql
-  gem 'puma', '5.2.1'
-  gem 'rails', '6.1.3'
+  gem 'puma', '~> 5.2.1'
+  gem 'rails', '~> 6.1.3'
+  gem 'redis', '~> 4.0'
   gem 'tzinfo-data', '1.2021.1'
 end

+ 11 - 9
frameworks/Ruby/rails/Gemfile.lock

@@ -64,7 +64,7 @@ GEM
     concurrent-ruby (1.1.8)
     crass (1.0.6)
     erubi (1.10.0)
-    ffi (1.14.2)
+    ffi (1.15.0)
     globalid (0.4.2)
       activesupport (>= 4.2.0)
     i18n (1.8.9)
@@ -82,14 +82,14 @@ GEM
     method_source (1.0.0)
     mimemagic (0.3.5)
     mini_mime (1.0.2)
-    minitest (5.14.3)
+    minitest (5.14.4)
     mysql2 (0.5.3)
-    nio4r (2.5.5)
-    nokogiri (1.11.1-arm64-darwin)
+    nio4r (2.5.7)
+    nokogiri (1.11.2-arm64-darwin)
       racc (~> 1.4)
-    oj (3.11.2)
+    oj (3.11.3)
     pg (1.2.3)
-    puma (5.2.1)
+    puma (5.2.2)
       nio4r (~> 2.0)
     racc (1.5.2)
     rack (2.2.3)
@@ -125,6 +125,7 @@ GEM
     rb-fsevent (0.10.4)
     rb-inotify (0.10.1)
       ffi (~> 1.0)
+    redis (4.2.5)
     sprockets (4.0.2)
       concurrent-ruby (~> 1.0)
       rack (> 1, < 3)
@@ -148,10 +149,11 @@ PLATFORMS
 DEPENDENCIES
   listen (~> 3.3)!
   mysql2 (= 0.5.3)!
-  oj (= 3.11.2)!
+  oj (~> 3.11.2)!
   pg (= 1.2.3)!
-  puma (= 5.2.1)!
-  rails (= 6.1.3)!
+  puma (~> 5.2.1)!
+  rails (~> 6.1.3)!
+  redis (~> 4.0)!
   tzinfo-data (= 1.2021.1)!
 
 BUNDLED WITH

+ 3 - 3
frameworks/Ruby/rails/README.md

@@ -17,12 +17,13 @@ The tests were run with:
 - [Puma 5.2.1](http://puma.io/)
 - [MySQL 5.5](https://dev.mysql.com/)
 - [PostgreSQL 11](https://www.postgresql.org/)
-
+- [Redis 5.0](https://redis.io)
 ## Paths & Source for Tests
 
 - [JSON Serialization](app/controllers/hello_world_controller.rb): "/json"
 - [Single Database Query](app/controllers/hello_world_controller.rb): "/db", [World Model](app/models/world.rb)
-- [Multiple Database Queries](app/controllers/hello_world_controller.rb): "/db?queries={#}", [World Model](app/models/world.rb)
+- [Multiple Database Queries](app/controllers/hello_world_controller.rb): "/queries?queries={#}", [World Model](app/models/world.rb)
+- [Cached Database Queries](app/controllers/hello_world_controller.rb): "/cached?queries={#}", [World Model]
 - [Fortunes](app/controllers/hello_world_controller.rb): "/fortune" , [Fortunes Model](app/models/fortune.rb)
 - [Database Updates](app/controllers/hello_world_controller.rb): "/update?queries={#}", [World Model](app/models/world.rb)
 - [Plaintext](app/controllers/hello_world_controller.rb): "/plaintext"
@@ -42,4 +43,3 @@ The tests were run with:
 ### Resources
 
 - [Ruby on Rails Source Code](https://github.com/rails/rails)
-- [PR: passenger-install-apache2-module doesn't work on ruby 2.0](https://github.com/FooBarWidget/passenger/pull/71)

+ 2 - 3
frameworks/Ruby/rails/app/controllers/application_controller.rb

@@ -1,11 +1,10 @@
+# frozen_string_literal: true
 class ApplicationController < ActionController::Base
-
   before_action :add_header
 
-protected
+  private
 
   def add_header
     response.set_header('Date', Time.now.httpdate)
   end
-
 end

+ 23 - 26
frameworks/Ruby/rails/app/controllers/hello_world_controller.rb

@@ -16,53 +16,50 @@ class HelloWorldController < ApplicationController
   end
 
   def query
-    queries = params[:queries].to_i
-    queries = 1 if queries < 1
-    queries = 500 if queries > 500
-
-    results = QUERY_RANGE.sample(queries).map do |id|
+    results = QUERY_RANGE.sample(query_count).map do |id|
       World.find(id)
     end
 
     render json: results
   end
 
+  def cached_query
+    results = QUERY_RANGE.sample(query_count).map do |id|
+      Rails.cache.fetch(id) do
+        World.find(id).as_json
+      end
+    end
+
+    render json: results
+  end
+
   def fortune
     @fortunes = Fortune.all.to_a
     @fortunes << Fortune.new(id: 0, message: 'Additional fortune added at request time.')
-    @fortunes = @fortunes.sort_by!(&:message)
+    @fortunes.sort_by!(&:message)
   end
 
   def update
-    queries = (params[:queries] || 1).to_i
-    queries = 1 if queries < 1
-    queries = 500 if queries > 500
-
-    worlds = queries.times.map{Random.rand(1..10_000)}.map do |id|
+    worlds = query_count.times.map { Random.rand(1..10_000) }.map do |id|
       # get a random row from the database, which we know has 10000
       # rows with ids 1 - 10000
-      world = World.select(:id, :randomNumber).find(id)
-      begin
-        rn = Random.rand(1..10_000)
-      end while rn == world.randomNumber
-      world.update_column(:randomNumber, rn)
+      world = World.find(id)
+      random = Random.rand(1..10_000)
+      random = Random.rand(1..10_000) until random != world.randomNumber
+      world.update_columns(randomNumber: random)
       world
     end
 
     render json: worlds
   end
 
-  def cached_query
-    queries = params[:queries].to_i
-    queries = 1 if queries < 1
-    queries = 500 if queries > 500
+  private
 
-    results = QUERY_RANGE.sample(queries).map do |id|
-      Rails.cache.fetch("world-#{id}") do
-        World.find(id)
-      end
-    end
+  def query_count
+    queries = params[:queries].to_i
+    return 1 if queries < 1
+    return 500 if queries > 500
 
-    render json: results
+    queries
   end
 end

+ 11 - 1
frameworks/Ruby/rails/config/environments/production.rb

@@ -28,7 +28,17 @@ Rails.application.configure do
   config.log_tags = [ :request_id ]
 
   # Use a different cache store in production.
-  config.cache_store = :memory_store
+  config.cache_store = :redis_cache_store, { 
+    url: ENV['REDIS_URL'],
+    connect_timeout:    30,  # Defaults to 20 seconds
+    read_timeout:       0.2, # Defaults to 1 second
+    write_timeout:      0.2, # Defaults to 1 second
+    reconnect_attempts: 1,   # Defaults to 0
+  
+    error_handler: -> (method:, returning:, exception:) {
+      puts "NO REDIS DETECTED"
+    }
+  }
 
   # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
   # the I18n.default_locale when a translation cannot be found).

+ 6 - 4
frameworks/Ruby/rails/rails-mysql.dockerfile

@@ -1,16 +1,18 @@
 FROM ruby:3.0
 
-ENV BUNDLE_WITHOUT=postgresql
-ENV RAILS_ENV=production_mysql
-ENV PORT=8080
+RUN apt-get update -yqq && apt-get install -yqq --no-install-recommends redis-server
 
 EXPOSE 8080
 WORKDIR /rails
 
 COPY ./Gemfile* /rails/
 
+ENV BUNDLE_WITHOUT=postgresql
 RUN bundle install --jobs=8
 
 COPY . /rails/
 
-CMD ["rails", "server"]
+ENV RAILS_ENV=production_mysql
+ENV PORT=8080
+ENV REDIS_URL=redis://localhost:6379/0/cache
+CMD ./run-with-redis.sh

+ 6 - 4
frameworks/Ruby/rails/rails.dockerfile

@@ -1,16 +1,18 @@
 FROM ruby:3.0
 
-ENV BUNDLE_WITHOUT=mysql
-ENV RAILS_ENV=production_postgresql
-ENV PORT=8080
+RUN apt-get update -yqq && apt-get install -yqq --no-install-recommends redis-server
 
 EXPOSE 8080
 WORKDIR /rails
 
 COPY ./Gemfile* /rails/
 
+ENV BUNDLE_WITHOUT=mysql
 RUN bundle install --jobs=8
 
 COPY . /rails/
 
-CMD ["rails", "server"]
+ENV RAILS_ENV=production_postgresql
+ENV PORT=8080
+ENV REDIS_URL=redis://localhost:6379/0/cache
+CMD ./run-with-redis.sh

+ 3 - 0
frameworks/Ruby/rails/run-with-redis.sh

@@ -0,0 +1,3 @@
+#!/bin/bash
+service redis-server start
+rails server

+ 1 - 0
toolset/.gitignore

@@ -0,0 +1 @@
+*.pyc