rage-rb 1.8.0 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/CHANGELOG.md +22 -0
 - data/Gemfile +1 -1
 - data/README.md +3 -2
 - data/lib/rage/cable/channel.rb +3 -5
 - data/lib/rage/cli.rb +164 -11
 - data/lib/rage/configuration.rb +36 -2
 - data/lib/rage/controller/api.rb +11 -7
 - data/lib/rage/ext/active_record/connection_pool.rb +68 -10
 - data/lib/rage/ext/setup.rb +72 -9
 - data/lib/rage/fiber.rb +41 -1
 - data/lib/rage/fiber_scheduler.rb +3 -3
 - data/lib/rage/logger/logger.rb +1 -1
 - data/lib/rage/rails.rb +4 -1
 - data/lib/rage/request.rb +39 -0
 - data/lib/rage/setup.rb +2 -2
 - data/lib/rage/tasks.rb +33 -0
 - data/lib/rage/templates/Rakefile +1 -0
 - data/lib/rage/templates/config-application.rb +3 -0
 - data/lib/rage/templates/config-environments-production.rb +2 -2
 - data/lib/rage/templates/db-templates/app-models-application_record.rb +3 -0
 - data/lib/rage/templates/db-templates/db-seeds.rb +9 -0
 - data/lib/rage/templates/db-templates/mysql/config-database.yml +24 -0
 - data/lib/rage/templates/db-templates/postgresql/config-database.yml +21 -0
 - data/lib/rage/templates/db-templates/sqlite3/config-database.yml +19 -0
 - data/lib/rage/templates/db-templates/trilogy/config-database.yml +24 -0
 - data/lib/rage/templates/lib-tasks-.keep +0 -0
 - data/lib/rage/templates/model-template/model.rb +2 -0
 - data/lib/rage/version.rb +1 -1
 - data/lib/rage-rb.rb +9 -2
 - data/rage.gemspec +2 -1
 - metadata +27 -4
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 11dd7f4039089ea1f06eb54c332851c1942f7dc646f48f20a648b9504681d61d
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: ed28d28bcee87dbbb59dcc200540b7b7588d68b3ace8821c55a014005314974a
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: fa1d951dcd7a0cb63fbcef9801298266f4bf61f515977dd3c311e7ea563df9dfcc383db282386f997257d35d01695168880aa160437166105aa8e73ada028295
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 7c8e571b08e8987ffec6dd31799382ad0c9da35b42fb7aa0988b146f3efac6e8cd35391410f1e2339191a58dbec81ee8bdb4f78728070fc0d4123a4e2e54f4f0
         
     | 
    
        data/CHANGELOG.md
    CHANGED
    
    | 
         @@ -1,5 +1,27 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ## [Unreleased]
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
      
 3 
     | 
    
         
            +
            ## [1.10.0] - 2024-09-16
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            ### Changed
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            - Enable Rage Connection Pool by default (#103).
         
     | 
| 
      
 8 
     | 
    
         
            +
            - Allow to preconfigure the app for selected database (#104).
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            ### Added
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            - Add `version` and `middleware` CLI commands (#99).
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            ## [1.9.0] - 2024-08-24
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            ### Added
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            - Static file server (#100).
         
     | 
| 
      
 19 
     | 
    
         
            +
            - Rails 7.2 compatibility (#101).
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            ### Fixed
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            - Correctly set Rails env (#102).
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
       3 
25 
     | 
    
         
             
            ## [1.8.0] - 2024-08-06
         
     | 
| 
       4 
26 
     | 
    
         | 
| 
       5 
27 
     | 
    
         
             
            ### Added
         
     | 
    
        data/Gemfile
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | 
         @@ -59,6 +59,7 @@ Also, see the following integration guides: 
     | 
|
| 
       59 
59 
     | 
    
         | 
| 
       60 
60 
     | 
    
         
             
            - [Rails integration](https://github.com/rage-rb/rage/wiki/Rails-integration)
         
     | 
| 
       61 
61 
     | 
    
         
             
            - [RSpec integration](https://github.com/rage-rb/rage/wiki/RSpec-integration)
         
     | 
| 
      
 62 
     | 
    
         
            +
            - [WebSockets guide](https://github.com/rage-rb/rage/wiki/WebSockets-guide)
         
     | 
| 
       62 
63 
     | 
    
         | 
| 
       63 
64 
     | 
    
         
             
            If you are a first-time contributor, make sure to check the [overview doc](https://github.com/rage-rb/rage/blob/master/OVERVIEW.md) that shows how Rage's core components interact with each other.
         
     | 
| 
       64 
65 
     | 
    
         | 
| 
         @@ -154,7 +155,7 @@ end 
     | 
|
| 
       154 
155 
     | 
    
         
             
            ```ruby
         
     | 
| 
       155 
156 
     | 
    
         
             
            class BenchmarksController < ApplicationController
         
     | 
| 
       156 
157 
     | 
    
         
             
              def show
         
     | 
| 
       157 
     | 
    
         
            -
                render json: World.find(rand(10_000))
         
     | 
| 
      
 158 
     | 
    
         
            +
                render json: World.find(rand(1..10_000))
         
     | 
| 
       158 
159 
     | 
    
         
             
              end
         
     | 
| 
       159 
160 
     | 
    
         
             
            end
         
     | 
| 
       160 
161 
     | 
    
         
             
            ```
         
     | 
| 
         @@ -172,8 +173,8 @@ Status | Changes 
     | 
|
| 
       172 
173 
     | 
    
         
             
            :white_check_mark: | ~~Automatic code reloading in development with Zeitwerk.~~
         
     | 
| 
       173 
174 
     | 
    
         
             
            :white_check_mark: | ~~Support conditional get with `etag` and `last_modified`.~~
         
     | 
| 
       174 
175 
     | 
    
         
             
            :white_check_mark: | ~~Expose the `cookies` and `session` objects.~~
         
     | 
| 
      
 176 
     | 
    
         
            +
            :white_check_mark: | ~~Implement Iodine-based equivalent of Action Cable.~~
         
     | 
| 
       175 
177 
     | 
    
         
             
            ⏳ | Expose the `send_data` and `send_file` methods.
         
     | 
| 
       176 
     | 
    
         
            -
            ⏳ | Implement Iodine-based equivalent of Action Cable.
         
     | 
| 
       177 
178 
     | 
    
         | 
| 
       178 
179 
     | 
    
         
             
            ## Development
         
     | 
| 
       179 
180 
     | 
    
         | 
    
        data/lib/rage/cable/channel.rb
    CHANGED
    
    | 
         @@ -135,7 +135,7 @@ class Rage::Cable::Channel 
     | 
|
| 
       135 
135 
     | 
    
         
             
                  end
         
     | 
| 
       136 
136 
     | 
    
         | 
| 
       137 
137 
     | 
    
         
             
                  is_subscribing = action_name == :subscribed
         
     | 
| 
       138 
     | 
    
         
            -
                   
     | 
| 
      
 138 
     | 
    
         
            +
                  should_release_connections = Rage.config.internal.should_manually_release_ar_connections?
         
     | 
| 
       139 
139 
     | 
    
         | 
| 
       140 
140 
     | 
    
         
             
                  method_name = class_eval <<~RUBY, __FILE__, __LINE__ + 1
         
     | 
| 
       141 
141 
     | 
    
         
             
                    def __run_#{action_name}(data)
         
     | 
| 
         @@ -163,12 +163,10 @@ class Rage::Cable::Channel 
     | 
|
| 
       163 
163 
     | 
    
         
             
                      #{periodic_timers_chunk}
         
     | 
| 
       164 
164 
     | 
    
         
             
                      #{rescue_handlers_chunk}
         
     | 
| 
       165 
165 
     | 
    
         | 
| 
       166 
     | 
    
         
            -
                      #{if  
     | 
| 
      
 166 
     | 
    
         
            +
                      #{if should_release_connections
         
     | 
| 
       167 
167 
     | 
    
         
             
                        <<~RUBY
         
     | 
| 
       168 
168 
     | 
    
         
             
                        ensure
         
     | 
| 
       169 
     | 
    
         
            -
                           
     | 
| 
       170 
     | 
    
         
            -
                            ActiveRecord::Base.connection_handler.clear_active_connections!
         
     | 
| 
       171 
     | 
    
         
            -
                          end
         
     | 
| 
      
 169 
     | 
    
         
            +
                          ActiveRecord::Base.connection_handler.clear_active_connections!(:all)
         
     | 
| 
       172 
170 
     | 
    
         
             
                        RUBY
         
     | 
| 
       173 
171 
     | 
    
         
             
                      end}
         
     | 
| 
       174 
172 
     | 
    
         
             
                    end
         
     | 
    
        data/lib/rage/cli.rb
    CHANGED
    
    | 
         @@ -2,17 +2,57 @@ 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            require "thor"
         
     | 
| 
       4 
4 
     | 
    
         
             
            require "rack"
         
     | 
| 
      
 5 
     | 
    
         
            +
            require "rage/version"
         
     | 
| 
       5 
6 
     | 
    
         | 
| 
       6 
7 
     | 
    
         
             
            module Rage
         
     | 
| 
      
 8 
     | 
    
         
            +
              class CLICodeGenerator < Thor
         
     | 
| 
      
 9 
     | 
    
         
            +
                include Thor::Actions
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                def self.source_root
         
     | 
| 
      
 12 
     | 
    
         
            +
                  File.expand_path("templates", __dir__)
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                desc "migration NAME", "Generate a new migration."
         
     | 
| 
      
 16 
     | 
    
         
            +
                def migration(name = nil)
         
     | 
| 
      
 17 
     | 
    
         
            +
                  return help("migration") if name.nil?
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  setup
         
     | 
| 
      
 20 
     | 
    
         
            +
                  Rake::Task["db:new_migration"].invoke(name)
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                desc "model NAME", "Generate a new model."
         
     | 
| 
      
 24 
     | 
    
         
            +
                def model(name = nil)
         
     | 
| 
      
 25 
     | 
    
         
            +
                  return help("model") if name.nil?
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                  setup
         
     | 
| 
      
 28 
     | 
    
         
            +
                  migration("create_#{name.pluralize}")
         
     | 
| 
      
 29 
     | 
    
         
            +
                  @model_name = name.classify
         
     | 
| 
      
 30 
     | 
    
         
            +
                  template("model-template/model.rb", "app/models/#{name.singularize.underscore}.rb")
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                private
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                def setup
         
     | 
| 
      
 36 
     | 
    
         
            +
                  @setup ||= begin
         
     | 
| 
      
 37 
     | 
    
         
            +
                    require "rake"
         
     | 
| 
      
 38 
     | 
    
         
            +
                    load "Rakefile"
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
                end
         
     | 
| 
      
 41 
     | 
    
         
            +
              end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
       7 
43 
     | 
    
         
             
              class CLI < Thor
         
     | 
| 
       8 
44 
     | 
    
         
             
                def self.exit_on_failure?
         
     | 
| 
       9 
45 
     | 
    
         
             
                  true
         
     | 
| 
       10 
46 
     | 
    
         
             
                end
         
     | 
| 
       11 
47 
     | 
    
         | 
| 
       12 
48 
     | 
    
         
             
                desc "new PATH", "Create a new application."
         
     | 
| 
       13 
     | 
    
         
            -
                 
     | 
| 
      
 49 
     | 
    
         
            +
                option :database, aliases: "-d", desc: "Preconfigure for selected database.", enum: %w(mysql trilogy postgresql sqlite3)
         
     | 
| 
      
 50 
     | 
    
         
            +
                option :help, aliases: "-h", desc: "Show this message."
         
     | 
| 
      
 51 
     | 
    
         
            +
                def new(path = nil)
         
     | 
| 
      
 52 
     | 
    
         
            +
                  return help("new") if options.help? || path.nil?
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
       14 
54 
     | 
    
         
             
                  require "rage/all"
         
     | 
| 
       15 
     | 
    
         
            -
                   
     | 
| 
      
 55 
     | 
    
         
            +
                  CLINewAppGenerator.start([path, options[:database]])
         
     | 
| 
       16 
56 
     | 
    
         
             
                end
         
     | 
| 
       17 
57 
     | 
    
         | 
| 
       18 
58 
     | 
    
         
             
                desc "s", "Start the app server."
         
     | 
| 
         @@ -29,12 +69,15 @@ module Rage 
     | 
|
| 
       29 
69 
     | 
    
         
             
                  app = ::Rack::Builder.parse_file(options[:config] || "config.ru")
         
     | 
| 
       30 
70 
     | 
    
         
             
                  app = app[0] if app.is_a?(Array)
         
     | 
| 
       31 
71 
     | 
    
         | 
| 
       32 
     | 
    
         
            -
                   
     | 
| 
       33 
     | 
    
         
            -
                  address = options[:binding] || (Rage.env.production? ? "0.0.0.0" : "localhost")
         
     | 
| 
       34 
     | 
    
         
            -
                  timeout = Rage.config.server.timeout
         
     | 
| 
       35 
     | 
    
         
            -
                  max_clients = Rage.config.server.max_clients
         
     | 
| 
      
 72 
     | 
    
         
            +
                  server_options = { service: :http, handler: app }
         
     | 
| 
       36 
73 
     | 
    
         | 
| 
       37 
     | 
    
         
            -
                   
     | 
| 
      
 74 
     | 
    
         
            +
                  server_options[:port] = options[:port] || Rage.config.server.port
         
     | 
| 
      
 75 
     | 
    
         
            +
                  server_options[:address] = options[:binding] || (Rage.env.production? ? "0.0.0.0" : "localhost")
         
     | 
| 
      
 76 
     | 
    
         
            +
                  server_options[:timeout] = Rage.config.server.timeout
         
     | 
| 
      
 77 
     | 
    
         
            +
                  server_options[:max_clients] = Rage.config.server.max_clients
         
     | 
| 
      
 78 
     | 
    
         
            +
                  server_options[:public] = Rage.config.public_file_server.enabled ? Rage.root.join("public").to_s : nil
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                  ::Iodine.listen(**server_options)
         
     | 
| 
       38 
81 
     | 
    
         
             
                  ::Iodine.threads = Rage.config.server.threads_count
         
     | 
| 
       39 
82 
     | 
    
         
             
                  ::Iodine.workers = Rage.config.server.workers_count
         
     | 
| 
       40 
83 
     | 
    
         | 
| 
         @@ -112,6 +155,57 @@ module Rage 
     | 
|
| 
       112 
155 
     | 
    
         
             
                  IRB.start
         
     | 
| 
       113 
156 
     | 
    
         
             
                end
         
     | 
| 
       114 
157 
     | 
    
         | 
| 
      
 158 
     | 
    
         
            +
                desc "middleware", "List Rack middleware stack enabled for the application"
         
     | 
| 
      
 159 
     | 
    
         
            +
                def middleware
         
     | 
| 
      
 160 
     | 
    
         
            +
                  environment
         
     | 
| 
      
 161 
     | 
    
         
            +
             
     | 
| 
      
 162 
     | 
    
         
            +
                  Rage.config.middleware.middlewares.each do |middleware|
         
     | 
| 
      
 163 
     | 
    
         
            +
                    say "use #{middleware.first.name}"
         
     | 
| 
      
 164 
     | 
    
         
            +
                  end
         
     | 
| 
      
 165 
     | 
    
         
            +
                end
         
     | 
| 
      
 166 
     | 
    
         
            +
             
     | 
| 
      
 167 
     | 
    
         
            +
                desc "version", "Return the current version of the framework"
         
     | 
| 
      
 168 
     | 
    
         
            +
                def version
         
     | 
| 
      
 169 
     | 
    
         
            +
                  puts Rage::VERSION
         
     | 
| 
      
 170 
     | 
    
         
            +
                end
         
     | 
| 
      
 171 
     | 
    
         
            +
             
     | 
| 
      
 172 
     | 
    
         
            +
                map "generate" => :g
         
     | 
| 
      
 173 
     | 
    
         
            +
                desc "g TYPE", "Generate new code."
         
     | 
| 
      
 174 
     | 
    
         
            +
                subcommand "g", CLICodeGenerator
         
     | 
| 
      
 175 
     | 
    
         
            +
             
     | 
| 
      
 176 
     | 
    
         
            +
                map "--tasks" => :tasks
         
     | 
| 
      
 177 
     | 
    
         
            +
                desc "--tasks", "See the list of available tasks."
         
     | 
| 
      
 178 
     | 
    
         
            +
                def tasks
         
     | 
| 
      
 179 
     | 
    
         
            +
                  require "io/console"
         
     | 
| 
      
 180 
     | 
    
         
            +
             
     | 
| 
      
 181 
     | 
    
         
            +
                  tasks = linked_rake_tasks
         
     | 
| 
      
 182 
     | 
    
         
            +
                  return if tasks.empty?
         
     | 
| 
      
 183 
     | 
    
         
            +
             
     | 
| 
      
 184 
     | 
    
         
            +
                  _, max_width = IO.console.winsize
         
     | 
| 
      
 185 
     | 
    
         
            +
                  max_task_name = tasks.max_by { |task| task.name.length }.name.length + 2
         
     | 
| 
      
 186 
     | 
    
         
            +
                  max_comment = max_width - max_task_name - 8
         
     | 
| 
      
 187 
     | 
    
         
            +
             
     | 
| 
      
 188 
     | 
    
         
            +
                  tasks.each do |task|
         
     | 
| 
      
 189 
     | 
    
         
            +
                    comment = task.comment.length <= max_comment ? task.comment : "#{task.comment[0...max_comment - 5]}..."
         
     | 
| 
      
 190 
     | 
    
         
            +
                    puts sprintf("rage %-#{max_task_name}s # %s", task.name, comment)
         
     | 
| 
      
 191 
     | 
    
         
            +
                  end
         
     | 
| 
      
 192 
     | 
    
         
            +
                end
         
     | 
| 
      
 193 
     | 
    
         
            +
             
     | 
| 
      
 194 
     | 
    
         
            +
                def method_missing(method_name, *, &)
         
     | 
| 
      
 195 
     | 
    
         
            +
                  set_env({})
         
     | 
| 
      
 196 
     | 
    
         
            +
             
     | 
| 
      
 197 
     | 
    
         
            +
                  if respond_to?(method_name)
         
     | 
| 
      
 198 
     | 
    
         
            +
                    Rake::Task[method_name].invoke
         
     | 
| 
      
 199 
     | 
    
         
            +
                  else
         
     | 
| 
      
 200 
     | 
    
         
            +
                    suggestions = linked_rake_tasks.map(&:name)
         
     | 
| 
      
 201 
     | 
    
         
            +
                    raise UndefinedCommandError.new(method_name.to_s, suggestions, nil)
         
     | 
| 
      
 202 
     | 
    
         
            +
                  end
         
     | 
| 
      
 203 
     | 
    
         
            +
                end
         
     | 
| 
      
 204 
     | 
    
         
            +
             
     | 
| 
      
 205 
     | 
    
         
            +
                def respond_to_missing?(method_name, include_private = false)
         
     | 
| 
      
 206 
     | 
    
         
            +
                  linked_rake_tasks.any? { |task| task.name == method_name.to_s } || super
         
     | 
| 
      
 207 
     | 
    
         
            +
                end
         
     | 
| 
      
 208 
     | 
    
         
            +
             
     | 
| 
       115 
209 
     | 
    
         
             
                private
         
     | 
| 
       116 
210 
     | 
    
         | 
| 
       117 
211 
     | 
    
         
             
                def environment
         
     | 
| 
         @@ -123,26 +217,85 @@ module Rage 
     | 
|
| 
       123 
217 
     | 
    
         
             
                end
         
     | 
| 
       124 
218 
     | 
    
         | 
| 
       125 
219 
     | 
    
         
             
                def set_env(options)
         
     | 
| 
       126 
     | 
    
         
            -
                   
     | 
| 
      
 220 
     | 
    
         
            +
                  if options[:environment]
         
     | 
| 
      
 221 
     | 
    
         
            +
                    ENV["RAGE_ENV"] = ENV["RAILS_ENV"] = options[:environment]
         
     | 
| 
      
 222 
     | 
    
         
            +
                  elsif ENV["RAGE_ENV"]
         
     | 
| 
      
 223 
     | 
    
         
            +
                    ENV["RAILS_ENV"] = ENV["RAGE_ENV"]
         
     | 
| 
      
 224 
     | 
    
         
            +
                  elsif ENV["RAILS_ENV"]
         
     | 
| 
      
 225 
     | 
    
         
            +
                    ENV["RAGE_ENV"] = ENV["RAILS_ENV"]
         
     | 
| 
      
 226 
     | 
    
         
            +
                  else
         
     | 
| 
      
 227 
     | 
    
         
            +
                    ENV["RAGE_ENV"] = ENV["RAILS_ENV"] = "development"
         
     | 
| 
      
 228 
     | 
    
         
            +
                  end
         
     | 
| 
      
 229 
     | 
    
         
            +
                end
         
     | 
| 
      
 230 
     | 
    
         
            +
             
     | 
| 
      
 231 
     | 
    
         
            +
                def linked_rake_tasks
         
     | 
| 
      
 232 
     | 
    
         
            +
                  require "rake"
         
     | 
| 
      
 233 
     | 
    
         
            +
                  Rake::TaskManager.record_task_metadata = true
         
     | 
| 
      
 234 
     | 
    
         
            +
                  load "Rakefile"
         
     | 
| 
      
 235 
     | 
    
         
            +
             
     | 
| 
      
 236 
     | 
    
         
            +
                  Rake::Task.tasks.select { |task| !task.comment.nil? && task.name.start_with?("db:") }
         
     | 
| 
       127 
237 
     | 
    
         
             
                end
         
     | 
| 
       128 
238 
     | 
    
         
             
              end
         
     | 
| 
       129 
239 
     | 
    
         | 
| 
       130 
     | 
    
         
            -
              class  
     | 
| 
      
 240 
     | 
    
         
            +
              class CLINewAppGenerator < Thor::Group
         
     | 
| 
       131 
241 
     | 
    
         
             
                include Thor::Actions
         
     | 
| 
       132 
242 
     | 
    
         
             
                argument :path, type: :string
         
     | 
| 
      
 243 
     | 
    
         
            +
                argument :database, type: :string, required: false
         
     | 
| 
       133 
244 
     | 
    
         | 
| 
       134 
245 
     | 
    
         
             
                def self.source_root
         
     | 
| 
       135 
246 
     | 
    
         
             
                  File.expand_path("templates", __dir__)
         
     | 
| 
       136 
247 
     | 
    
         
             
                end
         
     | 
| 
       137 
248 
     | 
    
         | 
| 
      
 249 
     | 
    
         
            +
                def setup
         
     | 
| 
      
 250 
     | 
    
         
            +
                  @use_database = !database.nil?
         
     | 
| 
      
 251 
     | 
    
         
            +
                end
         
     | 
| 
      
 252 
     | 
    
         
            +
             
     | 
| 
       138 
253 
     | 
    
         
             
                def create_directory
         
     | 
| 
       139 
254 
     | 
    
         
             
                  empty_directory(path)
         
     | 
| 
       140 
255 
     | 
    
         
             
                end
         
     | 
| 
       141 
256 
     | 
    
         | 
| 
       142 
257 
     | 
    
         
             
                def copy_files
         
     | 
| 
       143 
     | 
    
         
            -
                   
     | 
| 
      
 258 
     | 
    
         
            +
                  inject_templates
         
     | 
| 
      
 259 
     | 
    
         
            +
                end
         
     | 
| 
      
 260 
     | 
    
         
            +
             
     | 
| 
      
 261 
     | 
    
         
            +
                def install_database
         
     | 
| 
      
 262 
     | 
    
         
            +
                  return unless @use_database
         
     | 
| 
      
 263 
     | 
    
         
            +
             
     | 
| 
      
 264 
     | 
    
         
            +
                  @app_name = path.tr("-", "_").downcase
         
     | 
| 
      
 265 
     | 
    
         
            +
                  append_to_file "#{path}/Gemfile", <<~RUBY
         
     | 
| 
      
 266 
     | 
    
         
            +
             
     | 
| 
      
 267 
     | 
    
         
            +
                    gem "#{get_db_gem_name}"
         
     | 
| 
      
 268 
     | 
    
         
            +
                    gem "activerecord"
         
     | 
| 
      
 269 
     | 
    
         
            +
                    gem "standalone_migrations", require: false
         
     | 
| 
      
 270 
     | 
    
         
            +
                  RUBY
         
     | 
| 
      
 271 
     | 
    
         
            +
             
     | 
| 
      
 272 
     | 
    
         
            +
                  inject_templates("db-templates")
         
     | 
| 
      
 273 
     | 
    
         
            +
                  inject_templates("db-templates/#{database}")
         
     | 
| 
      
 274 
     | 
    
         
            +
                end
         
     | 
| 
      
 275 
     | 
    
         
            +
             
     | 
| 
      
 276 
     | 
    
         
            +
                private
         
     | 
| 
      
 277 
     | 
    
         
            +
             
     | 
| 
      
 278 
     | 
    
         
            +
                def inject_templates(from = nil)
         
     | 
| 
      
 279 
     | 
    
         
            +
                  root = "#{self.class.source_root}/#{from}"
         
     | 
| 
      
 280 
     | 
    
         
            +
             
     | 
| 
      
 281 
     | 
    
         
            +
                  Dir.glob("*", base: root).each do |template|
         
     | 
| 
      
 282 
     | 
    
         
            +
                    next if File.directory?("#{root}/#{template}")
         
     | 
| 
      
 283 
     | 
    
         
            +
             
     | 
| 
       144 
284 
     | 
    
         
             
                    *template_path_parts, template_name = template.split("-")
         
     | 
| 
       145 
     | 
    
         
            -
                    template( 
     | 
| 
      
 285 
     | 
    
         
            +
                    template("#{root}/#{template}", [path, *template_path_parts, template_name].join("/"))
         
     | 
| 
      
 286 
     | 
    
         
            +
                  end
         
     | 
| 
      
 287 
     | 
    
         
            +
                end
         
     | 
| 
      
 288 
     | 
    
         
            +
             
     | 
| 
      
 289 
     | 
    
         
            +
                def get_db_gem_name
         
     | 
| 
      
 290 
     | 
    
         
            +
                  case database
         
     | 
| 
      
 291 
     | 
    
         
            +
                  when "mysql"
         
     | 
| 
      
 292 
     | 
    
         
            +
                    "mysql2"
         
     | 
| 
      
 293 
     | 
    
         
            +
                  when "trilogy"
         
     | 
| 
      
 294 
     | 
    
         
            +
                    "trilogy"
         
     | 
| 
      
 295 
     | 
    
         
            +
                  when "postgresql"
         
     | 
| 
      
 296 
     | 
    
         
            +
                    "pg"
         
     | 
| 
      
 297 
     | 
    
         
            +
                  when "sqlite3"
         
     | 
| 
      
 298 
     | 
    
         
            +
                    "sqlite3"
         
     | 
| 
       146 
299 
     | 
    
         
             
                  end
         
     | 
| 
       147 
300 
     | 
    
         
             
                end
         
     | 
| 
       148 
301 
     | 
    
         
             
              end
         
     | 
    
        data/lib/rage/configuration.rb
    CHANGED
    
    | 
         @@ -102,6 +102,12 @@ 
     | 
|
| 
       102 
102 
     | 
    
         
             
            #
         
     | 
| 
       103 
103 
     | 
    
         
             
            # > Specifies connection timeout.
         
     | 
| 
       104 
104 
     | 
    
         
             
            #
         
     | 
| 
      
 105 
     | 
    
         
            +
            # # Static file server
         
     | 
| 
      
 106 
     | 
    
         
            +
            #
         
     | 
| 
      
 107 
     | 
    
         
            +
            # • _config.public_file_server.enabled_
         
     | 
| 
      
 108 
     | 
    
         
            +
            #
         
     | 
| 
      
 109 
     | 
    
         
            +
            # > Configures whether Rage should serve static files from the public directory. Defaults to `false`.
         
     | 
| 
      
 110 
     | 
    
         
            +
            #
         
     | 
| 
       105 
111 
     | 
    
         
             
            # # Cable Configuration
         
     | 
| 
       106 
112 
     | 
    
         
             
            #
         
     | 
| 
       107 
113 
     | 
    
         
             
            # • _config.cable.protocol_
         
     | 
| 
         @@ -124,9 +130,13 @@ 
     | 
|
| 
       124 
130 
     | 
    
         
             
            #
         
     | 
| 
       125 
131 
     | 
    
         
             
            # > Disables the `io_write` hook to fix the ["zero-length iov"](https://bugs.ruby-lang.org/issues/19640) error on Ruby < 3.3.
         
     | 
| 
       126 
132 
     | 
    
         
             
            #
         
     | 
| 
       127 
     | 
    
         
            -
            # •  
     | 
| 
      
 133 
     | 
    
         
            +
            # • _RAGE_DISABLE_AR_POOL_PATCH_
         
     | 
| 
      
 134 
     | 
    
         
            +
            #
         
     | 
| 
      
 135 
     | 
    
         
            +
            # > Disables the `ActiveRecord::ConnectionPool` patch and makes Rage use the original ActiveRecord implementation.
         
     | 
| 
       128 
136 
     | 
    
         
             
            #
         
     | 
| 
       129 
     | 
    
         
            -
            #  
     | 
| 
      
 137 
     | 
    
         
            +
            # • _RAGE_DISABLE_AR_WEAK_CONNECTIONS_
         
     | 
| 
      
 138 
     | 
    
         
            +
            #
         
     | 
| 
      
 139 
     | 
    
         
            +
            # > Instructs Rage to not reuse Active Record connections between different fibers.
         
     | 
| 
       130 
140 
     | 
    
         
             
            #
         
     | 
| 
       131 
141 
     | 
    
         
             
            class Rage::Configuration
         
     | 
| 
       132 
142 
     | 
    
         
             
              attr_accessor :logger
         
     | 
| 
         @@ -165,6 +175,10 @@ class Rage::Configuration 
     | 
|
| 
       165 
175 
     | 
    
         
             
                @cable ||= Cable.new
         
     | 
| 
       166 
176 
     | 
    
         
             
              end
         
     | 
| 
       167 
177 
     | 
    
         | 
| 
      
 178 
     | 
    
         
            +
              def public_file_server
         
     | 
| 
      
 179 
     | 
    
         
            +
                @public_file_server ||= PublicFileServer.new
         
     | 
| 
      
 180 
     | 
    
         
            +
              end
         
     | 
| 
      
 181 
     | 
    
         
            +
             
     | 
| 
       168 
182 
     | 
    
         
             
              def internal
         
     | 
| 
       169 
183 
     | 
    
         
             
                @internal ||= Internal.new
         
     | 
| 
       170 
184 
     | 
    
         
             
              end
         
     | 
| 
         @@ -246,10 +260,30 @@ class Rage::Configuration 
     | 
|
| 
       246 
260 
     | 
    
         
             
                end
         
     | 
| 
       247 
261 
     | 
    
         
             
              end
         
     | 
| 
       248 
262 
     | 
    
         | 
| 
      
 263 
     | 
    
         
            +
              class PublicFileServer
         
     | 
| 
      
 264 
     | 
    
         
            +
                attr_accessor :enabled
         
     | 
| 
      
 265 
     | 
    
         
            +
              end
         
     | 
| 
      
 266 
     | 
    
         
            +
             
     | 
| 
       249 
267 
     | 
    
         
             
              # @private
         
     | 
| 
       250 
268 
     | 
    
         
             
              class Internal
         
     | 
| 
       251 
269 
     | 
    
         
             
                attr_accessor :rails_mode
         
     | 
| 
       252 
270 
     | 
    
         | 
| 
      
 271 
     | 
    
         
            +
                def patch_ar_pool?
         
     | 
| 
      
 272 
     | 
    
         
            +
                  !ENV["RAGE_DISABLE_AR_POOL_PATCH"] && !Rage.env.test?
         
     | 
| 
      
 273 
     | 
    
         
            +
                end
         
     | 
| 
      
 274 
     | 
    
         
            +
             
     | 
| 
      
 275 
     | 
    
         
            +
                # whether we should manually release AR connections;
         
     | 
| 
      
 276 
     | 
    
         
            +
                # AR 7.2+ uses `with_connection` internaly, so we only need to do this for older versions;
         
     | 
| 
      
 277 
     | 
    
         
            +
                def should_manually_release_ar_connections?
         
     | 
| 
      
 278 
     | 
    
         
            +
                  defined?(ActiveRecord) && ActiveRecord.version < Gem::Version.create("7.2.0")
         
     | 
| 
      
 279 
     | 
    
         
            +
                end
         
     | 
| 
      
 280 
     | 
    
         
            +
             
     | 
| 
      
 281 
     | 
    
         
            +
                # whether we should manually reconnect closed AR connections;
         
     | 
| 
      
 282 
     | 
    
         
            +
                # AR 7.1+ does this automatically while executing the query;
         
     | 
| 
      
 283 
     | 
    
         
            +
                def should_manually_restore_ar_connections?
         
     | 
| 
      
 284 
     | 
    
         
            +
                  defined?(ActiveRecord) && ActiveRecord.version < Gem::Version.create("7.1.0")
         
     | 
| 
      
 285 
     | 
    
         
            +
                end
         
     | 
| 
      
 286 
     | 
    
         
            +
             
     | 
| 
       253 
287 
     | 
    
         
             
                def inspect
         
     | 
| 
       254 
288 
     | 
    
         
             
                  "#<#{self.class.name}>"
         
     | 
| 
       255 
289 
     | 
    
         
             
                end
         
     | 
    
        data/lib/rage/controller/api.rb
    CHANGED
    
    | 
         @@ -76,8 +76,6 @@ class RageController::API 
     | 
|
| 
       76 
76 
     | 
    
         
             
                    ""
         
     | 
| 
       77 
77 
     | 
    
         
             
                  end
         
     | 
| 
       78 
78 
     | 
    
         | 
| 
       79 
     | 
    
         
            -
                  activerecord_loaded = defined?(::ActiveRecord)
         
     | 
| 
       80 
     | 
    
         
            -
             
     | 
| 
       81 
79 
     | 
    
         
             
                  wrap_parameters_chunk = if __wrap_parameters_key
         
     | 
| 
       82 
80 
     | 
    
         
             
                    <<~RUBY
         
     | 
| 
       83 
81 
     | 
    
         
             
                      wrap_key = self.class.__wrap_parameters_key
         
     | 
| 
         @@ -95,9 +93,12 @@ class RageController::API 
     | 
|
| 
       95 
93 
     | 
    
         
             
                    RUBY
         
     | 
| 
       96 
94 
     | 
    
         
             
                  end
         
     | 
| 
       97 
95 
     | 
    
         | 
| 
      
 96 
     | 
    
         
            +
                  query_cache_enabled = defined?(::ActiveRecord)
         
     | 
| 
      
 97 
     | 
    
         
            +
                  should_release_connections = Rage.config.internal.should_manually_release_ar_connections?
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
       98 
99 
     | 
    
         
             
                  class_eval <<~RUBY, __FILE__, __LINE__ + 1
         
     | 
| 
       99 
100 
     | 
    
         
             
                    def __run_#{action}
         
     | 
| 
       100 
     | 
    
         
            -
                      #{if  
     | 
| 
      
 101 
     | 
    
         
            +
                      #{if query_cache_enabled
         
     | 
| 
       101 
102 
     | 
    
         
             
                        <<~RUBY
         
     | 
| 
       102 
103 
     | 
    
         
             
                          ActiveRecord::Base.connection_pool.enable_query_cache!
         
     | 
| 
       103 
104 
     | 
    
         
             
                        RUBY
         
     | 
| 
         @@ -119,12 +120,15 @@ class RageController::API 
     | 
|
| 
       119 
120 
     | 
    
         
             
                      #{rescue_handlers_chunk}
         
     | 
| 
       120 
121 
     | 
    
         | 
| 
       121 
122 
     | 
    
         
             
                    ensure
         
     | 
| 
       122 
     | 
    
         
            -
                      #{if  
     | 
| 
      
 123 
     | 
    
         
            +
                      #{if query_cache_enabled
         
     | 
| 
       123 
124 
     | 
    
         
             
                        <<~RUBY
         
     | 
| 
       124 
125 
     | 
    
         
             
                          ActiveRecord::Base.connection_pool.disable_query_cache!
         
     | 
| 
       125 
     | 
    
         
            -
             
     | 
| 
       126 
     | 
    
         
            -
             
     | 
| 
       127 
     | 
    
         
            -
             
     | 
| 
      
 126 
     | 
    
         
            +
                        RUBY
         
     | 
| 
      
 127 
     | 
    
         
            +
                      end}
         
     | 
| 
      
 128 
     | 
    
         
            +
             
     | 
| 
      
 129 
     | 
    
         
            +
                      #{if should_release_connections
         
     | 
| 
      
 130 
     | 
    
         
            +
                        <<~RUBY
         
     | 
| 
      
 131 
     | 
    
         
            +
                          ActiveRecord::Base.connection_handler.clear_active_connections!(:all)
         
     | 
| 
       128 
132 
     | 
    
         
             
                        RUBY
         
     | 
| 
       129 
133 
     | 
    
         
             
                      end}
         
     | 
| 
       130 
134 
     | 
    
         | 
| 
         @@ -24,11 +24,30 @@ module Rage::Ext::ActiveRecord::ConnectionPool 
     | 
|
| 
       24 
24 
     | 
    
         
             
                end
         
     | 
| 
       25 
25 
     | 
    
         
             
              end
         
     | 
| 
       26 
26 
     | 
    
         | 
| 
      
 27 
     | 
    
         
            +
              # reconnect closed connections on checkout;
         
     | 
| 
      
 28 
     | 
    
         
            +
              # only included with `Rage.config.should_manually_restore_ar_connections?`
         
     | 
| 
      
 29 
     | 
    
         
            +
              module ConnectionWithVerify
         
     | 
| 
      
 30 
     | 
    
         
            +
                def connection
         
     | 
| 
      
 31 
     | 
    
         
            +
                  conn = super
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                  if conn.__needs_reconnect
         
     | 
| 
      
 34 
     | 
    
         
            +
                    conn.reconnect!
         
     | 
| 
      
 35 
     | 
    
         
            +
                    conn.__needs_reconnect = false
         
     | 
| 
      
 36 
     | 
    
         
            +
                  end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                  conn
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
              end
         
     | 
| 
      
 41 
     | 
    
         
            +
              if Rage.config.internal.should_manually_restore_ar_connections?
         
     | 
| 
      
 42 
     | 
    
         
            +
                prepend ConnectionWithVerify
         
     | 
| 
      
 43 
     | 
    
         
            +
              end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
       27 
45 
     | 
    
         
             
              def self.extended(instance)
         
     | 
| 
       28 
46 
     | 
    
         
             
                instance.class.alias_method :__checkout__, :checkout
         
     | 
| 
       29 
47 
     | 
    
         
             
                instance.class.alias_method :__remove__, :remove
         
     | 
| 
       30 
48 
     | 
    
         | 
| 
       31 
49 
     | 
    
         
             
                ActiveRecord::ConnectionAdapters::AbstractAdapter.attr_accessor(:__idle_since)
         
     | 
| 
      
 50 
     | 
    
         
            +
                ActiveRecord::ConnectionAdapters::AbstractAdapter.attr_accessor(:__needs_reconnect)
         
     | 
| 
       32 
51 
     | 
    
         
             
              end
         
     | 
| 
       33 
52 
     | 
    
         | 
| 
       34 
53 
     | 
    
         
             
              def __init_rage_extension
         
     | 
| 
         @@ -47,7 +66,7 @@ module Rage::Ext::ActiveRecord::ConnectionPool 
     | 
|
| 
       47 
66 
     | 
    
         
             
                @__checkout_timeout = checkout_timeout
         
     | 
| 
       48 
67 
     | 
    
         | 
| 
       49 
68 
     | 
    
         
             
                # how long a connection can be idle for before disconnecting
         
     | 
| 
       50 
     | 
    
         
            -
                @__idle_timeout =  
     | 
| 
      
 69 
     | 
    
         
            +
                @__idle_timeout = respond_to?(:db_config) ? db_config.idle_timeout : @idle_timeout
         
     | 
| 
       51 
70 
     | 
    
         | 
| 
       52 
71 
     | 
    
         
             
                # how often should we check for fibers that wait for a connection for too long
         
     | 
| 
       53 
72 
     | 
    
         
             
                @__timeout_worker_frequency = 0.5
         
     | 
| 
         @@ -65,8 +84,30 @@ module Rage::Ext::ActiveRecord::ConnectionPool 
     | 
|
| 
       65 
84 
     | 
    
         
             
                  end
         
     | 
| 
       66 
85 
     | 
    
         
             
                end
         
     | 
| 
       67 
86 
     | 
    
         | 
| 
      
 87 
     | 
    
         
            +
                # monitor connections health
         
     | 
| 
      
 88 
     | 
    
         
            +
                if Rage.config.internal.should_manually_restore_ar_connections?
         
     | 
| 
      
 89 
     | 
    
         
            +
                  Iodine.run_every(1_000) do
         
     | 
| 
      
 90 
     | 
    
         
            +
                    i = 0
         
     | 
| 
      
 91 
     | 
    
         
            +
                    while i < @__connections.length
         
     | 
| 
      
 92 
     | 
    
         
            +
                      conn = @__connections[i]
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
                      unless conn.__needs_reconnect
         
     | 
| 
      
 95 
     | 
    
         
            +
                        needs_reconnect = !conn.active? rescue true
         
     | 
| 
      
 96 
     | 
    
         
            +
                        if needs_reconnect
         
     | 
| 
      
 97 
     | 
    
         
            +
                          conn.__needs_reconnect = true
         
     | 
| 
      
 98 
     | 
    
         
            +
                          conn.disconnect!
         
     | 
| 
      
 99 
     | 
    
         
            +
                        end
         
     | 
| 
      
 100 
     | 
    
         
            +
                      end
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
                      i += 1
         
     | 
| 
      
 103 
     | 
    
         
            +
                    end
         
     | 
| 
      
 104 
     | 
    
         
            +
                  end
         
     | 
| 
      
 105 
     | 
    
         
            +
                end
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
                @release_connection_channel = "ext:ar-connection-released:#{object_id}"
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
       68 
109 
     | 
    
         
             
                # resume blocked fibers once connections become available
         
     | 
| 
       69 
     | 
    
         
            -
                Iodine.subscribe( 
     | 
| 
      
 110 
     | 
    
         
            +
                Iodine.subscribe(@release_connection_channel) do
         
     | 
| 
       70 
111 
     | 
    
         
             
                  if @__blocked.length > 0 && @__connections.length > 0
         
     | 
| 
       71 
112 
     | 
    
         
             
                    f, _ = @__blocked.shift
         
     | 
| 
       72 
113 
     | 
    
         
             
                    f.resume
         
     | 
| 
         @@ -75,7 +116,7 @@ module Rage::Ext::ActiveRecord::ConnectionPool 
     | 
|
| 
       75 
116 
     | 
    
         | 
| 
       76 
117 
     | 
    
         
             
                # unsubscribe on shutdown
         
     | 
| 
       77 
118 
     | 
    
         
             
                Iodine.on_state(:on_finish) do
         
     | 
| 
       78 
     | 
    
         
            -
                  Iodine.unsubscribe( 
     | 
| 
      
 119 
     | 
    
         
            +
                  Iodine.unsubscribe(@release_connection_channel)
         
     | 
| 
       79 
120 
     | 
    
         
             
                end
         
     | 
| 
       80 
121 
     | 
    
         
             
              end
         
     | 
| 
       81 
122 
     | 
    
         | 
| 
         @@ -100,7 +141,7 @@ module Rage::Ext::ActiveRecord::ConnectionPool 
     | 
|
| 
       100 
141 
     | 
    
         
             
                if (conn = @__in_use.delete(owner))
         
     | 
| 
       101 
142 
     | 
    
         
             
                  conn.__idle_since = Process.clock_gettime(Process::CLOCK_MONOTONIC)
         
     | 
| 
       102 
143 
     | 
    
         
             
                  @__connections << conn
         
     | 
| 
       103 
     | 
    
         
            -
                  Iodine.publish( 
     | 
| 
      
 144 
     | 
    
         
            +
                  Iodine.publish(@release_connection_channel, "", Iodine::PubSub::PROCESS) if @__blocked.length > 0
         
     | 
| 
       104 
145 
     | 
    
         
             
                end
         
     | 
| 
       105 
146 
     | 
    
         | 
| 
       106 
147 
     | 
    
         
             
                conn
         
     | 
| 
         @@ -108,20 +149,27 @@ module Rage::Ext::ActiveRecord::ConnectionPool 
     | 
|
| 
       108 
149 
     | 
    
         | 
| 
       109 
150 
     | 
    
         
             
              # Recover lost connections for the pool.
         
     | 
| 
       110 
151 
     | 
    
         
             
              def reap
         
     | 
| 
      
 152 
     | 
    
         
            +
                crashed_fibers = nil
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
       111 
154 
     | 
    
         
             
                @__in_use.each do |fiber, conn|
         
     | 
| 
       112 
155 
     | 
    
         
             
                  unless fiber.alive?
         
     | 
| 
       113 
156 
     | 
    
         
             
                    if conn.active?
         
     | 
| 
       114 
157 
     | 
    
         
             
                      conn.reset!
         
     | 
| 
       115 
     | 
    
         
            -
                       
     | 
| 
      
 158 
     | 
    
         
            +
                      (crashed_fibers ||= []) << fiber
         
     | 
| 
       116 
159 
     | 
    
         
             
                    else
         
     | 
| 
       117 
160 
     | 
    
         
             
                      @__in_use.delete(fiber)
         
     | 
| 
       118 
161 
     | 
    
         
             
                      conn.disconnect!
         
     | 
| 
       119 
162 
     | 
    
         
             
                      __remove__(conn)
         
     | 
| 
      
 163 
     | 
    
         
            +
                      self.automatic_reconnect = true
         
     | 
| 
       120 
164 
     | 
    
         
             
                      @__connections += build_new_connections(1)
         
     | 
| 
       121 
     | 
    
         
            -
                      Iodine.publish( 
     | 
| 
      
 165 
     | 
    
         
            +
                      Iodine.publish(@release_connection_channel, "", Iodine::PubSub::PROCESS) if @__blocked.length > 0
         
     | 
| 
       122 
166 
     | 
    
         
             
                    end
         
     | 
| 
       123 
167 
     | 
    
         
             
                  end
         
     | 
| 
       124 
168 
     | 
    
         
             
                end
         
     | 
| 
      
 169 
     | 
    
         
            +
             
     | 
| 
      
 170 
     | 
    
         
            +
                if crashed_fibers
         
     | 
| 
      
 171 
     | 
    
         
            +
                  crashed_fibers.each { |fiber| release_connection(fiber) }
         
     | 
| 
      
 172 
     | 
    
         
            +
                end
         
     | 
| 
       125 
173 
     | 
    
         
             
              end
         
     | 
| 
       126 
174 
     | 
    
         | 
| 
       127 
175 
     | 
    
         
             
              # Disconnect all connections that have been idle for at least
         
     | 
| 
         @@ -135,6 +183,7 @@ module Rage::Ext::ActiveRecord::ConnectionPool 
     | 
|
| 
       135 
183 
     | 
    
         
             
                  conn = @__connections[i]
         
     | 
| 
       136 
184 
     | 
    
         
             
                  if conn.__idle_since && current_time - conn.__idle_since >= minimum_idle
         
     | 
| 
       137 
185 
     | 
    
         
             
                    conn.__idle_since = nil
         
     | 
| 
      
 186 
     | 
    
         
            +
                    conn.__needs_reconnect = true
         
     | 
| 
       138 
187 
     | 
    
         
             
                    conn.disconnect!
         
     | 
| 
       139 
188 
     | 
    
         
             
                  end
         
     | 
| 
       140 
189 
     | 
    
         
             
                  i += 1
         
     | 
| 
         @@ -148,10 +197,14 @@ module Rage::Ext::ActiveRecord::ConnectionPool 
     | 
|
| 
       148 
197 
     | 
    
         
             
              end
         
     | 
| 
       149 
198 
     | 
    
         | 
| 
       150 
199 
     | 
    
         
             
              # Yields a connection from the connection pool to the block.
         
     | 
| 
       151 
     | 
    
         
            -
              def with_connection
         
     | 
| 
       152 
     | 
    
         
            -
                 
     | 
| 
      
 200 
     | 
    
         
            +
              def with_connection(_ = nil)
         
     | 
| 
      
 201 
     | 
    
         
            +
                unless (conn = @__in_use[Fiber.current])
         
     | 
| 
      
 202 
     | 
    
         
            +
                  conn = connection
         
     | 
| 
      
 203 
     | 
    
         
            +
                  fresh_connection = true
         
     | 
| 
      
 204 
     | 
    
         
            +
                end
         
     | 
| 
      
 205 
     | 
    
         
            +
                yield conn
         
     | 
| 
       153 
206 
     | 
    
         
             
              ensure
         
     | 
| 
       154 
     | 
    
         
            -
                release_connection
         
     | 
| 
      
 207 
     | 
    
         
            +
                release_connection if fresh_connection
         
     | 
| 
       155 
208 
     | 
    
         
             
              end
         
     | 
| 
       156 
209 
     | 
    
         | 
| 
       157 
210 
     | 
    
         
             
              # Returns an array containing the connections currently in the pool.
         
     | 
| 
         @@ -208,11 +261,12 @@ module Rage::Ext::ActiveRecord::ConnectionPool 
     | 
|
| 
       208 
261 
     | 
    
         
             
                end
         
     | 
| 
       209 
262 
     | 
    
         | 
| 
       210 
263 
     | 
    
         
             
                # create a new pool
         
     | 
| 
      
 264 
     | 
    
         
            +
                self.automatic_reconnect = true
         
     | 
| 
       211 
265 
     | 
    
         
             
                @__connections = build_new_connections
         
     | 
| 
       212 
266 
     | 
    
         | 
| 
       213 
267 
     | 
    
         
             
                # notify blocked fibers that there are new connections available
         
     | 
| 
       214 
268 
     | 
    
         
             
                [@__blocked.length, @__connections.length].min.times do
         
     | 
| 
       215 
     | 
    
         
            -
                  Iodine.publish( 
     | 
| 
      
 269 
     | 
    
         
            +
                  Iodine.publish(@release_connection_channel, "", Iodine::PubSub::PROCESS)
         
     | 
| 
       216 
270 
     | 
    
         
             
                end
         
     | 
| 
       217 
271 
     | 
    
         
             
              end
         
     | 
| 
       218 
272 
     | 
    
         | 
| 
         @@ -230,6 +284,10 @@ module Rage::Ext::ActiveRecord::ConnectionPool 
     | 
|
| 
       230 
284 
     | 
    
         
             
                connection
         
     | 
| 
       231 
285 
     | 
    
         
             
              end
         
     | 
| 
       232 
286 
     | 
    
         | 
| 
      
 287 
     | 
    
         
            +
              def lease_connection
         
     | 
| 
      
 288 
     | 
    
         
            +
                connection
         
     | 
| 
      
 289 
     | 
    
         
            +
              end
         
     | 
| 
      
 290 
     | 
    
         
            +
             
     | 
| 
       233 
291 
     | 
    
         
             
              # Check in a database connection back into the pool, indicating that you no longer need this connection.
         
     | 
| 
       234 
292 
     | 
    
         
             
              def checkin(conn)
         
     | 
| 
       235 
293 
     | 
    
         
             
                fiber = @__in_use.key(conn)
         
     | 
    
        data/lib/rage/ext/setup.rb
    CHANGED
    
    | 
         @@ -1,19 +1,45 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            if defined?(ActiveRecord) && ActiveRecord.version < Gem::Version.create("6")
         
     | 
| 
      
 2 
     | 
    
         
            +
              fail "Rage is only compatible with Active Record 6+. Detected Active Record version: #{ActiveRecord.version}."
         
     | 
| 
      
 3 
     | 
    
         
            +
            end
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
       1 
5 
     | 
    
         
             
            # set ActiveSupport isolation level
         
     | 
| 
       2 
6 
     | 
    
         
             
            if defined?(ActiveSupport::IsolatedExecutionState)
         
     | 
| 
       3 
7 
     | 
    
         
             
              ActiveSupport::IsolatedExecutionState.isolation_level = :fiber
         
     | 
| 
       4 
8 
     | 
    
         
             
            end
         
     | 
| 
       5 
9 
     | 
    
         | 
| 
      
 10 
     | 
    
         
            +
            # patch Active Record 6.0 to accept the role argument
         
     | 
| 
      
 11 
     | 
    
         
            +
            if defined?(ActiveRecord) && ActiveRecord.version < Gem::Version.create("6.1")
         
     | 
| 
      
 12 
     | 
    
         
            +
              %i(active_connections? connection_pool_list clear_active_connections!).each do |m|
         
     | 
| 
      
 13 
     | 
    
         
            +
                ActiveRecord::Base.connection_handler.define_singleton_method(m) do |_ = nil|
         
     | 
| 
      
 14 
     | 
    
         
            +
                  super()
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
            end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
       6 
19 
     | 
    
         
             
            # release ActiveRecord connections on yield
         
     | 
| 
       7 
     | 
    
         
            -
            if defined?(ActiveRecord) &&  
     | 
| 
       8 
     | 
    
         
            -
               
     | 
| 
       9 
     | 
    
         
            -
                 
     | 
| 
       10 
     | 
    
         
            -
                   
     | 
| 
      
 20 
     | 
    
         
            +
            if defined?(ActiveRecord) && Rage.config.internal.patch_ar_pool?
         
     | 
| 
      
 21 
     | 
    
         
            +
              if ENV["RAGE_DISABLE_AR_WEAK_CONNECTIONS"]
         
     | 
| 
      
 22 
     | 
    
         
            +
                unless Rage.config.internal.should_manually_release_ar_connections?
         
     | 
| 
      
 23 
     | 
    
         
            +
                  puts "WARNING: The RAGE_DISABLE_AR_WEAK_CONNECTIONS setting does not have any effect with Active Record 7.2+"
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
              elsif Rage.config.internal.should_manually_release_ar_connections?
         
     | 
| 
      
 26 
     | 
    
         
            +
                class Fiber
         
     | 
| 
      
 27 
     | 
    
         
            +
                  def self.defer(fileno)
         
     | 
| 
      
 28 
     | 
    
         
            +
                    f = Fiber.current
         
     | 
| 
      
 29 
     | 
    
         
            +
                    f.__awaited_fileno = fileno
         
     | 
| 
       11 
30 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
      
 31 
     | 
    
         
            +
                    res = Fiber.yield
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                    if ActiveRecord::Base.connection_handler.active_connections?(:all)
         
     | 
| 
      
 34 
     | 
    
         
            +
                      Iodine.defer do
         
     | 
| 
      
 35 
     | 
    
         
            +
                        if fileno != f.__awaited_fileno || !f.alive?
         
     | 
| 
      
 36 
     | 
    
         
            +
                          ActiveRecord::Base.connection_handler.connection_pool_list(:all).each { |pool| pool.release_connection(f) }
         
     | 
| 
      
 37 
     | 
    
         
            +
                        end
         
     | 
| 
      
 38 
     | 
    
         
            +
                      end
         
     | 
| 
      
 39 
     | 
    
         
            +
                    end
         
     | 
| 
       15 
40 
     | 
    
         | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
      
 41 
     | 
    
         
            +
                    res
         
     | 
| 
      
 42 
     | 
    
         
            +
                  end
         
     | 
| 
       17 
43 
     | 
    
         
             
                end
         
     | 
| 
       18 
44 
     | 
    
         
             
              end
         
     | 
| 
       19 
45 
     | 
    
         
             
            end
         
     | 
| 
         @@ -30,7 +56,44 @@ if defined?(ActiveRecord::ConnectionAdapters::ConnectionPool) 
     | 
|
| 
       30 
56 
     | 
    
         
             
              end
         
     | 
| 
       31 
57 
     | 
    
         
             
            end
         
     | 
| 
       32 
58 
     | 
    
         | 
| 
      
 59 
     | 
    
         
            +
            # connect to the database in standalone mode
         
     | 
| 
      
 60 
     | 
    
         
            +
            database_url, database_file = ENV["DATABASE_URL"], Rage.root.join("config/database.yml")
         
     | 
| 
      
 61 
     | 
    
         
            +
            if defined?(ActiveRecord) && !Rage.config.internal.rails_mode && (database_url || database_file.exist?)
         
     | 
| 
      
 62 
     | 
    
         
            +
              # transform database URL to an object
         
     | 
| 
      
 63 
     | 
    
         
            +
              database_url_config = if database_url.nil?
         
     | 
| 
      
 64 
     | 
    
         
            +
                {}
         
     | 
| 
      
 65 
     | 
    
         
            +
              elsif ActiveRecord.version >= Gem::Version.create("6.1.0")
         
     | 
| 
      
 66 
     | 
    
         
            +
                ActiveRecord::Base.configurations
         
     | 
| 
      
 67 
     | 
    
         
            +
                ActiveRecord::DatabaseConfigurations::ConnectionUrlResolver.new(database_url).to_hash
         
     | 
| 
      
 68 
     | 
    
         
            +
              else
         
     | 
| 
      
 69 
     | 
    
         
            +
                ActiveRecord::ConnectionAdapters::ConnectionSpecification::ConnectionUrlResolver.new(database_url).to_hash
         
     | 
| 
      
 70 
     | 
    
         
            +
              end
         
     | 
| 
      
 71 
     | 
    
         
            +
              database_url_config.transform_keys!(&:to_s)
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
              # load config/database.yml
         
     | 
| 
      
 74 
     | 
    
         
            +
              if database_file.exist?
         
     | 
| 
      
 75 
     | 
    
         
            +
                database_file_config = begin
         
     | 
| 
      
 76 
     | 
    
         
            +
                  require "yaml"
         
     | 
| 
      
 77 
     | 
    
         
            +
                  require "erb"
         
     | 
| 
      
 78 
     | 
    
         
            +
                  YAML.safe_load(ERB.new(database_file.read).result, aliases: true)
         
     | 
| 
      
 79 
     | 
    
         
            +
                end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                # merge database URL config into the file config (only if we have one database)
         
     | 
| 
      
 82 
     | 
    
         
            +
                database_file_config.transform_values! do |env_config|
         
     | 
| 
      
 83 
     | 
    
         
            +
                  env_config.all? { |_, v| v.is_a?(Hash) } ? env_config : env_config.merge(database_url_config)
         
     | 
| 
      
 84 
     | 
    
         
            +
                end
         
     | 
| 
      
 85 
     | 
    
         
            +
              end
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
              ActiveRecord::Base.configurations = database_file_config || { Rage.env.to_s => database_url_config }
         
     | 
| 
      
 88 
     | 
    
         
            +
              ActiveRecord::Base.establish_connection(Rage.env.to_sym)
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
              unless defined?(Rake)
         
     | 
| 
      
 91 
     | 
    
         
            +
                ActiveRecord::Base.logger = Rage.logger if Rage.logger.debug?
         
     | 
| 
      
 92 
     | 
    
         
            +
                ActiveRecord::Base.connection_pool.with_connection {} # validate the connection
         
     | 
| 
      
 93 
     | 
    
         
            +
              end
         
     | 
| 
      
 94 
     | 
    
         
            +
            end
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
       33 
96 
     | 
    
         
             
            # patch `ActiveRecord::ConnectionPool`
         
     | 
| 
       34 
     | 
    
         
            -
            if defined?(ActiveRecord) &&  
     | 
| 
      
 97 
     | 
    
         
            +
            if defined?(ActiveRecord) && !defined?(Rake) && Rage.config.internal.patch_ar_pool?
         
     | 
| 
       35 
98 
     | 
    
         
             
              Rage.patch_active_record_connection_pool
         
     | 
| 
       36 
99 
     | 
    
         
             
            end
         
     | 
    
        data/lib/rage/fiber.rb
    CHANGED
    
    | 
         @@ -39,6 +39,43 @@ 
     | 
|
| 
       39 
39 
     | 
    
         
             
            # Many developers see fibers as "lightweight threads" that should be used in conjunction with fiber pools, the same way we use thread pools for threads.<br>
         
     | 
| 
       40 
40 
     | 
    
         
             
            # Instead, it makes sense to think of fibers as regular Ruby objects. We don't use a pool of arrays when we need to create an array - we create a new object and let Ruby and the GC do their job.<br>
         
     | 
| 
       41 
41 
     | 
    
         
             
            # Same applies to fibers. Feel free to create as many fibers as you need on demand.
         
     | 
| 
      
 42 
     | 
    
         
            +
            #
         
     | 
| 
      
 43 
     | 
    
         
            +
            # ## Active Record Connections
         
     | 
| 
      
 44 
     | 
    
         
            +
            #
         
     | 
| 
      
 45 
     | 
    
         
            +
            # Let's consider the following controller, where we update a record in the database:
         
     | 
| 
      
 46 
     | 
    
         
            +
            #
         
     | 
| 
      
 47 
     | 
    
         
            +
            # ```ruby
         
     | 
| 
      
 48 
     | 
    
         
            +
            # class UsersController < RageController::API
         
     | 
| 
      
 49 
     | 
    
         
            +
            #   def update
         
     | 
| 
      
 50 
     | 
    
         
            +
            #     User.update!(params[:id], email: params[:email])
         
     | 
| 
      
 51 
     | 
    
         
            +
            #     render status: :ok
         
     | 
| 
      
 52 
     | 
    
         
            +
            #   end
         
     | 
| 
      
 53 
     | 
    
         
            +
            # end
         
     | 
| 
      
 54 
     | 
    
         
            +
            # ```
         
     | 
| 
      
 55 
     | 
    
         
            +
            #
         
     | 
| 
      
 56 
     | 
    
         
            +
            # The `User.update!` call here checks out an Active Record connection, and Rage will automatically check it back in once the action is completed. So far so good!
         
     | 
| 
      
 57 
     | 
    
         
            +
            #
         
     | 
| 
      
 58 
     | 
    
         
            +
            # Let's consider another example:
         
     | 
| 
      
 59 
     | 
    
         
            +
            #
         
     | 
| 
      
 60 
     | 
    
         
            +
            # ```ruby
         
     | 
| 
      
 61 
     | 
    
         
            +
            # require "net/http"
         
     | 
| 
      
 62 
     | 
    
         
            +
            #
         
     | 
| 
      
 63 
     | 
    
         
            +
            # class UsersController < RageController::API
         
     | 
| 
      
 64 
     | 
    
         
            +
            #   def update
         
     | 
| 
      
 65 
     | 
    
         
            +
            #     User.update!(params[:id], email: params[:email]) # takes 5ms
         
     | 
| 
      
 66 
     | 
    
         
            +
            #     Net::HTTP.post_form(URI("https://mailing.service/update"), { user_id: params[:id] }) # takes 50ms
         
     | 
| 
      
 67 
     | 
    
         
            +
            #     render status: :ok
         
     | 
| 
      
 68 
     | 
    
         
            +
            #   end
         
     | 
| 
      
 69 
     | 
    
         
            +
            # end
         
     | 
| 
      
 70 
     | 
    
         
            +
            # ```
         
     | 
| 
      
 71 
     | 
    
         
            +
            #
         
     | 
| 
      
 72 
     | 
    
         
            +
            # Here, we've added another step: once the record is updated, we will send a request to update the user's data in the mailing list service.
         
     | 
| 
      
 73 
     | 
    
         
            +
            #
         
     | 
| 
      
 74 
     | 
    
         
            +
            # However, in this case, we want to release the Active Record connection before the action is completed. You can see that we need the connection only for the `User.update!` call.
         
     | 
| 
      
 75 
     | 
    
         
            +
            # The next 50ms the code will spend waiting for the HTTP request to finish, and if we don't release the Active Record connection right away, other fibers won't be able to use it.
         
     | 
| 
      
 76 
     | 
    
         
            +
            #
         
     | 
| 
      
 77 
     | 
    
         
            +
            # Active Record 7.2 handles this case by using [#with_connection](https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/ConnectionPool.html#method-i-with_connection) internally.
         
     | 
| 
      
 78 
     | 
    
         
            +
            # With older Active Record versions, Rage handles this case on its own by keeping track of blocking calls and releasing Active Record connections between them.
         
     | 
| 
       42 
79 
     | 
    
         
             
            class Fiber
         
     | 
| 
       43 
80 
     | 
    
         
             
              # @private
         
     | 
| 
       44 
81 
     | 
    
         
             
              AWAIT_ERROR_MESSAGE = "err"
         
     | 
| 
         @@ -81,6 +118,9 @@ class Fiber 
     | 
|
| 
       81 
118 
     | 
    
         
             
                "block:#{object_id}:#{@__block_channel_i}"
         
     | 
| 
       82 
119 
     | 
    
         
             
              end
         
     | 
| 
       83 
120 
     | 
    
         | 
| 
      
 121 
     | 
    
         
            +
              # @private
         
     | 
| 
      
 122 
     | 
    
         
            +
              attr_accessor :__awaited_fileno
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
       84 
124 
     | 
    
         
             
              # @private
         
     | 
| 
       85 
125 
     | 
    
         
             
              # pause a fiber and resume in the next iteration of the event loop
         
     | 
| 
       86 
126 
     | 
    
         
             
              def self.pause
         
     | 
| 
         @@ -138,7 +178,7 @@ class Fiber 
     | 
|
| 
       138 
178 
     | 
    
         
             
                  end
         
     | 
| 
       139 
179 
     | 
    
         
             
                end
         
     | 
| 
       140 
180 
     | 
    
         | 
| 
       141 
     | 
    
         
            -
                Fiber. 
     | 
| 
      
 181 
     | 
    
         
            +
                Fiber.defer(-1)
         
     | 
| 
       142 
182 
     | 
    
         
             
                Iodine.defer { Iodine.unsubscribe("await:#{f.object_id}") }
         
     | 
| 
       143 
183 
     | 
    
         | 
| 
       144 
184 
     | 
    
         
             
                # if num_wait_for is not 0 means we exited prematurely because of an error
         
     | 
    
        data/lib/rage/fiber_scheduler.rb
    CHANGED
    
    | 
         @@ -14,9 +14,9 @@ class Rage::FiberScheduler 
     | 
|
| 
       14 
14 
     | 
    
         
             
                f = Fiber.current
         
     | 
| 
       15 
15 
     | 
    
         
             
                ::Iodine::Scheduler.attach(io.fileno, events, timeout&.ceil || 0) { |err| f.resume(err) }
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
       17 
     | 
    
         
            -
                err = Fiber.defer
         
     | 
| 
       18 
     | 
    
         
            -
                if err  
     | 
| 
       19 
     | 
    
         
            -
                   
     | 
| 
      
 17 
     | 
    
         
            +
                err = Fiber.defer(io.fileno)
         
     | 
| 
      
 18 
     | 
    
         
            +
                if err && err < 0
         
     | 
| 
      
 19 
     | 
    
         
            +
                  err
         
     | 
| 
       20 
20 
     | 
    
         
             
                else
         
     | 
| 
       21 
21 
     | 
    
         
             
                  events
         
     | 
| 
       22 
22 
     | 
    
         
             
                end
         
     | 
    
        data/lib/rage/logger/logger.rb
    CHANGED
    
    
    
        data/lib/rage/rails.rb
    CHANGED
    
    | 
         @@ -44,7 +44,10 @@ end 
     | 
|
| 
       44 
44 
     | 
    
         
             
            # clone Rails logger
         
     | 
| 
       45 
45 
     | 
    
         
             
            Rails.configuration.after_initialize do
         
     | 
| 
       46 
46 
     | 
    
         
             
              if Rails.logger && !Rage.logger
         
     | 
| 
       47 
     | 
    
         
            -
                rails_logdev = Rails.logger. 
     | 
| 
      
 47 
     | 
    
         
            +
                rails_logdev = Rails.logger.yield_self { |logger|
         
     | 
| 
      
 48 
     | 
    
         
            +
                  logger.respond_to?(:broadcasts) ? logger.broadcasts.last : logger
         
     | 
| 
      
 49 
     | 
    
         
            +
                }.instance_variable_get(:@logdev)
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
       48 
51 
     | 
    
         
             
                Rage.configure do
         
     | 
| 
       49 
52 
     | 
    
         
             
                  config.logger = Rage::Logger.new(rails_logdev.dev) if rails_logdev.is_a?(Logger::LogDevice)
         
     | 
| 
       50 
53 
     | 
    
         
             
                end
         
     | 
    
        data/lib/rage/request.rb
    CHANGED
    
    | 
         @@ -37,6 +37,45 @@ class Rage::Request 
     | 
|
| 
       37 
37 
     | 
    
         
             
                )
         
     | 
| 
       38 
38 
     | 
    
         
             
              end
         
     | 
| 
       39 
39 
     | 
    
         | 
| 
      
 40 
     | 
    
         
            +
              # Returns the full URL of the request.
         
     | 
| 
      
 41 
     | 
    
         
            +
              # @example
         
     | 
| 
      
 42 
     | 
    
         
            +
              #   request.url # => "https://example.com/users?show_archived=true"
         
     | 
| 
      
 43 
     | 
    
         
            +
              def url
         
     | 
| 
      
 44 
     | 
    
         
            +
                scheme = @env["rack.url_scheme"]
         
     | 
| 
      
 45 
     | 
    
         
            +
                host = @env["SERVER_NAME"]
         
     | 
| 
      
 46 
     | 
    
         
            +
                port = @env["SERVER_PORT"]
         
     | 
| 
      
 47 
     | 
    
         
            +
                path = @env["PATH_INFO"]
         
     | 
| 
      
 48 
     | 
    
         
            +
                query_string = @env["QUERY_STRING"]
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                port_part = (scheme == "http" && port == "80") || (scheme == "https" && port == "443") ? "" : ":#{port}"
         
     | 
| 
      
 51 
     | 
    
         
            +
                query_part = query_string.empty? ? "" : "?#{query_string}"
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                "#{scheme}://#{host}#{port_part}#{path}#{query_part}"
         
     | 
| 
      
 54 
     | 
    
         
            +
              end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
              # Returns the path of the request.
         
     | 
| 
      
 57 
     | 
    
         
            +
              # @example
         
     | 
| 
      
 58 
     | 
    
         
            +
              #   request.path # => "/users"
         
     | 
| 
      
 59 
     | 
    
         
            +
              def path
         
     | 
| 
      
 60 
     | 
    
         
            +
                @env["PATH_INFO"]
         
     | 
| 
      
 61 
     | 
    
         
            +
              end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
              # Returns the full path including the query string.
         
     | 
| 
      
 64 
     | 
    
         
            +
              # @example
         
     | 
| 
      
 65 
     | 
    
         
            +
              #   request.fullpath # => "/users?show_archived=true"
         
     | 
| 
      
 66 
     | 
    
         
            +
              def fullpath
         
     | 
| 
      
 67 
     | 
    
         
            +
                path = @env["PATH_INFO"]
         
     | 
| 
      
 68 
     | 
    
         
            +
                query_string = @env["QUERY_STRING"]
         
     | 
| 
      
 69 
     | 
    
         
            +
                query_string.empty? ? path : "#{path}?#{query_string}"
         
     | 
| 
      
 70 
     | 
    
         
            +
              end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
              # Returns the user agent of the request.
         
     | 
| 
      
 73 
     | 
    
         
            +
              # @example
         
     | 
| 
      
 74 
     | 
    
         
            +
              #  request.user_agent # => "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
         
     | 
| 
      
 75 
     | 
    
         
            +
              def user_agent
         
     | 
| 
      
 76 
     | 
    
         
            +
                @env["HTTP_USER_AGENT"]
         
     | 
| 
      
 77 
     | 
    
         
            +
              end
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
       40 
79 
     | 
    
         
             
              private
         
     | 
| 
       41 
80 
     | 
    
         | 
| 
       42 
81 
     | 
    
         
             
              def if_none_match
         
     | 
    
        data/lib/rage/setup.rb
    CHANGED
    
    | 
         @@ -9,9 +9,9 @@ end 
     | 
|
| 
       9 
9 
     | 
    
         
             
            # Run application initializers
         
     | 
| 
       10 
10 
     | 
    
         
             
            Dir["#{Rage.root}/config/initializers/**/*.rb"].each { |initializer| load(initializer) }
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
      
 12 
     | 
    
         
            +
            require "rage/ext/setup"
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
       12 
14 
     | 
    
         
             
            # Load application classes
         
     | 
| 
       13 
15 
     | 
    
         
             
            Rage.code_loader.setup
         
     | 
| 
       14 
16 
     | 
    
         | 
| 
       15 
17 
     | 
    
         
             
            require_relative "#{Rage.root}/config/routes"
         
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
            require "rage/ext/setup"
         
     | 
    
        data/lib/rage/tasks.rb
    ADDED
    
    | 
         @@ -0,0 +1,33 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            begin
         
     | 
| 
      
 2 
     | 
    
         
            +
              require "standalone_migrations"
         
     | 
| 
      
 3 
     | 
    
         
            +
            rescue LoadError
         
     | 
| 
      
 4 
     | 
    
         
            +
            end
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            class Rage::Tasks
         
     | 
| 
      
 7 
     | 
    
         
            +
              class << self
         
     | 
| 
      
 8 
     | 
    
         
            +
                def init
         
     | 
| 
      
 9 
     | 
    
         
            +
                  load_db_tasks if defined?(StandaloneMigrations)
         
     | 
| 
      
 10 
     | 
    
         
            +
                end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                private
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                def load_db_tasks
         
     | 
| 
      
 15 
     | 
    
         
            +
                  StandaloneMigrations::Configurator.prepend(Module.new do
         
     | 
| 
      
 16 
     | 
    
         
            +
                    def configuration_file
         
     | 
| 
      
 17 
     | 
    
         
            +
                      @path ||= begin
         
     | 
| 
      
 18 
     | 
    
         
            +
                        @__tempfile = Tempfile.new
         
     | 
| 
      
 19 
     | 
    
         
            +
                        @__tempfile.write <<~YAML
         
     | 
| 
      
 20 
     | 
    
         
            +
                          config:
         
     | 
| 
      
 21 
     | 
    
         
            +
                            database: config/database.yml
         
     | 
| 
      
 22 
     | 
    
         
            +
                        YAML
         
     | 
| 
      
 23 
     | 
    
         
            +
                        @__tempfile.close
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                        @__tempfile.path
         
     | 
| 
      
 26 
     | 
    
         
            +
                      end
         
     | 
| 
      
 27 
     | 
    
         
            +
                    end
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end)
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                  StandaloneMigrations::Tasks.load_tasks
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/rage/templates/Rakefile
    CHANGED
    
    
| 
         @@ -1,11 +1,11 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            Rage.configure do
         
     | 
| 
       2 
2 
     | 
    
         
             
              # Specify the number of server processes to run. Defaults to number of CPU cores.
         
     | 
| 
       3 
     | 
    
         
            -
              # config.server.workers_count = ENV.fetch("WEB_CONCURRENCY", 1)
         
     | 
| 
      
 3 
     | 
    
         
            +
              # config.server.workers_count = ENV.fetch("WEB_CONCURRENCY", 1).to_i
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
5 
     | 
    
         
             
              # Specify the port the server will listen on.
         
     | 
| 
       6 
6 
     | 
    
         
             
              config.server.port = 3000
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
       8 
8 
     | 
    
         
             
              # Specify the logger
         
     | 
| 
       9 
     | 
    
         
            -
              config.logger = Rage::Logger.new( 
     | 
| 
      
 9 
     | 
    
         
            +
              config.logger = Rage::Logger.new(STDOUT)
         
     | 
| 
       10 
10 
     | 
    
         
             
              config.log_level = Logger::INFO
         
     | 
| 
       11 
11 
     | 
    
         
             
            end
         
     | 
| 
         @@ -0,0 +1,9 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # This file should ensure the existence of records required to run the application in every environment (production,
         
     | 
| 
      
 2 
     | 
    
         
            +
            # development, test). The code here should be idempotent so that it can be executed at any point in every environment.
         
     | 
| 
      
 3 
     | 
    
         
            +
            # The data can then be loaded with the bin/rails db:seed command (or created alongside the database with db:setup).
         
     | 
| 
      
 4 
     | 
    
         
            +
            #
         
     | 
| 
      
 5 
     | 
    
         
            +
            # Example:
         
     | 
| 
      
 6 
     | 
    
         
            +
            #
         
     | 
| 
      
 7 
     | 
    
         
            +
            #   ["Action", "Comedy", "Drama", "Horror"].each do |genre_name|
         
     | 
| 
      
 8 
     | 
    
         
            +
            #     MovieGenre.find_or_create_by!(name: genre_name)
         
     | 
| 
      
 9 
     | 
    
         
            +
            #   end
         
     | 
| 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ##
         
     | 
| 
      
 2 
     | 
    
         
            +
            # MySQL. Versions 5.5.8 and up are supported.
         
     | 
| 
      
 3 
     | 
    
         
            +
            #
         
     | 
| 
      
 4 
     | 
    
         
            +
            default: &default
         
     | 
| 
      
 5 
     | 
    
         
            +
              adapter: mysql2
         
     | 
| 
      
 6 
     | 
    
         
            +
              encoding: utf8mb4
         
     | 
| 
      
 7 
     | 
    
         
            +
              pool: <%%= ENV.fetch("DB_MAX_CONNECTIONS") { 5 } %>
         
     | 
| 
      
 8 
     | 
    
         
            +
              username: root
         
     | 
| 
      
 9 
     | 
    
         
            +
              password:
         
     | 
| 
      
 10 
     | 
    
         
            +
              socket: /tmp/mysql.sock
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            development:
         
     | 
| 
      
 13 
     | 
    
         
            +
              <<: *default
         
     | 
| 
      
 14 
     | 
    
         
            +
              database: <%= @app_name %>_development
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            test:
         
     | 
| 
      
 17 
     | 
    
         
            +
              <<: *default
         
     | 
| 
      
 18 
     | 
    
         
            +
              database: <%= @app_name %>_test
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            production:
         
     | 
| 
      
 21 
     | 
    
         
            +
              <<: *default
         
     | 
| 
      
 22 
     | 
    
         
            +
              database: <%= @app_name %>_production
         
     | 
| 
      
 23 
     | 
    
         
            +
              username: <%= @app_name %>
         
     | 
| 
      
 24 
     | 
    
         
            +
              password: <%%= ENV["<%= @app_name.upcase %>_DATABASE_PASSWORD"] %>
         
     | 
| 
         @@ -0,0 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ##
         
     | 
| 
      
 2 
     | 
    
         
            +
            # PostgreSQL. Versions 9.3 and up are supported.
         
     | 
| 
      
 3 
     | 
    
         
            +
            #
         
     | 
| 
      
 4 
     | 
    
         
            +
            default: &default
         
     | 
| 
      
 5 
     | 
    
         
            +
              adapter: postgresql
         
     | 
| 
      
 6 
     | 
    
         
            +
              encoding: unicode
         
     | 
| 
      
 7 
     | 
    
         
            +
              pool: <%%= ENV.fetch("DB_MAX_CONNECTIONS") { 5 } %>
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            development:
         
     | 
| 
      
 10 
     | 
    
         
            +
              <<: *default
         
     | 
| 
      
 11 
     | 
    
         
            +
              database: <%= @app_name %>_development
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            test:
         
     | 
| 
      
 14 
     | 
    
         
            +
              <<: *default
         
     | 
| 
      
 15 
     | 
    
         
            +
              database: <%= @app_name %>_test
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            production:
         
     | 
| 
      
 18 
     | 
    
         
            +
              <<: *default
         
     | 
| 
      
 19 
     | 
    
         
            +
              database: <%= @app_name %>_production
         
     | 
| 
      
 20 
     | 
    
         
            +
              username: <%= @app_name %>
         
     | 
| 
      
 21 
     | 
    
         
            +
              password: <%%= ENV["<%= @app_name.upcase %>_DATABASE_PASSWORD"] %>
         
     | 
| 
         @@ -0,0 +1,19 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ##
         
     | 
| 
      
 2 
     | 
    
         
            +
            # SQLite. Versions 3.8.0 and up are supported.
         
     | 
| 
      
 3 
     | 
    
         
            +
            #
         
     | 
| 
      
 4 
     | 
    
         
            +
            default: &default
         
     | 
| 
      
 5 
     | 
    
         
            +
              adapter: sqlite3
         
     | 
| 
      
 6 
     | 
    
         
            +
              pool: <%%= ENV.fetch("DB_MAX_CONNECTIONS") { 5 } %>
         
     | 
| 
      
 7 
     | 
    
         
            +
              timeout: 5000
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            development:
         
     | 
| 
      
 10 
     | 
    
         
            +
              <<: *default
         
     | 
| 
      
 11 
     | 
    
         
            +
              database: storage/development.sqlite3
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            test:
         
     | 
| 
      
 14 
     | 
    
         
            +
              <<: *default
         
     | 
| 
      
 15 
     | 
    
         
            +
              database: storage/test.sqlite3
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            production:
         
     | 
| 
      
 18 
     | 
    
         
            +
              <<: *default
         
     | 
| 
      
 19 
     | 
    
         
            +
              database: storage/production.sqlite3
         
     | 
| 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ##
         
     | 
| 
      
 2 
     | 
    
         
            +
            # MySQL. Versions 5.5.8 and up are supported.
         
     | 
| 
      
 3 
     | 
    
         
            +
            #
         
     | 
| 
      
 4 
     | 
    
         
            +
            default: &default
         
     | 
| 
      
 5 
     | 
    
         
            +
              adapter: trilogy
         
     | 
| 
      
 6 
     | 
    
         
            +
              encoding: utf8mb4
         
     | 
| 
      
 7 
     | 
    
         
            +
              pool: <%%= ENV.fetch("DB_MAX_THREADS") { 5 } %>
         
     | 
| 
      
 8 
     | 
    
         
            +
              username: root
         
     | 
| 
      
 9 
     | 
    
         
            +
              password:
         
     | 
| 
      
 10 
     | 
    
         
            +
              socket: /tmp/mysql.sock
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            development:
         
     | 
| 
      
 13 
     | 
    
         
            +
              <<: *default
         
     | 
| 
      
 14 
     | 
    
         
            +
              database: <%= @app_name %>_development
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            test:
         
     | 
| 
      
 17 
     | 
    
         
            +
              <<: *default
         
     | 
| 
      
 18 
     | 
    
         
            +
              database: <%= @app_name %>_test
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            production:
         
     | 
| 
      
 21 
     | 
    
         
            +
              <<: *default
         
     | 
| 
      
 22 
     | 
    
         
            +
              database: <%= @app_name %>_production
         
     | 
| 
      
 23 
     | 
    
         
            +
              username: <%= @app_name %>
         
     | 
| 
      
 24 
     | 
    
         
            +
              password: <%%= ENV["<%= @app_name.upcase %>_DATABASE_PASSWORD"] %>
         
     | 
| 
         
            File without changes
         
     | 
    
        data/lib/rage/version.rb
    CHANGED
    
    
    
        data/lib/rage-rb.rb
    CHANGED
    
    | 
         @@ -65,8 +65,10 @@ module Rage 
     | 
|
| 
       65 
65 
     | 
    
         
             
                  if is_connected
         
     | 
| 
       66 
66 
     | 
    
         
             
                    puts "INFO: Patching ActiveRecord::ConnectionPool"
         
     | 
| 
       67 
67 
     | 
    
         
             
                    Iodine.on_state(:on_start) do
         
     | 
| 
       68 
     | 
    
         
            -
                      ActiveRecord::Base. 
     | 
| 
       69 
     | 
    
         
            -
             
     | 
| 
      
 68 
     | 
    
         
            +
                      ActiveRecord::Base.connection_handler.connection_pool_list(:all).each do |pool|
         
     | 
| 
      
 69 
     | 
    
         
            +
                        pool.extend(Rage::Ext::ActiveRecord::ConnectionPool)
         
     | 
| 
      
 70 
     | 
    
         
            +
                        pool.__init_rage_extension
         
     | 
| 
      
 71 
     | 
    
         
            +
                      end
         
     | 
| 
       70 
72 
     | 
    
         
             
                    end
         
     | 
| 
       71 
73 
     | 
    
         
             
                  else
         
     | 
| 
       72 
74 
     | 
    
         
             
                    puts "WARNING: DB connection is not established - can't patch ActiveRecord::ConnectionPool"
         
     | 
| 
         @@ -80,6 +82,10 @@ module Rage 
     | 
|
| 
       80 
82 
     | 
    
         
             
                end
         
     | 
| 
       81 
83 
     | 
    
         
             
              end
         
     | 
| 
       82 
84 
     | 
    
         | 
| 
      
 85 
     | 
    
         
            +
              def self.load_tasks
         
     | 
| 
      
 86 
     | 
    
         
            +
                Rage::Tasks.init
         
     | 
| 
      
 87 
     | 
    
         
            +
              end
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
       83 
89 
     | 
    
         
             
              # @private
         
     | 
| 
       84 
90 
     | 
    
         
             
              def self.with_middlewares(app, middlewares)
         
     | 
| 
       85 
91 
     | 
    
         
             
                middlewares.reverse.inject(app) do |next_in_chain, (middleware, args, block)|
         
     | 
| 
         @@ -111,6 +117,7 @@ module Rage 
     | 
|
| 
       111 
117 
     | 
    
         
             
                end
         
     | 
| 
       112 
118 
     | 
    
         
             
              end
         
     | 
| 
       113 
119 
     | 
    
         | 
| 
      
 120 
     | 
    
         
            +
              autoload :Tasks, "rage/tasks"
         
     | 
| 
       114 
121 
     | 
    
         
             
              autoload :Cookies, "rage/cookies"
         
     | 
| 
       115 
122 
     | 
    
         
             
              autoload :Session, "rage/session"
         
     | 
| 
       116 
123 
     | 
    
         
             
              autoload :Cable, "rage/cable/cable"
         
     | 
    
        data/rage.gemspec
    CHANGED
    
    | 
         @@ -29,7 +29,8 @@ Gem::Specification.new do |spec| 
     | 
|
| 
       29 
29 
     | 
    
         | 
| 
       30 
30 
     | 
    
         
             
              spec.add_dependency "thor", "~> 1.0"
         
     | 
| 
       31 
31 
     | 
    
         
             
              spec.add_dependency "rack", "~> 2.0"
         
     | 
| 
       32 
     | 
    
         
            -
              spec.add_dependency "rage-iodine", "~>  
     | 
| 
      
 32 
     | 
    
         
            +
              spec.add_dependency "rage-iodine", "~> 4.0"
         
     | 
| 
       33 
33 
     | 
    
         
             
              spec.add_dependency "zeitwerk", "~> 2.6"
         
     | 
| 
       34 
34 
     | 
    
         
             
              spec.add_dependency "rack-test", "~> 2.1"
         
     | 
| 
      
 35 
     | 
    
         
            +
              spec.add_dependency "rake", ">= 12.0"
         
     | 
| 
       35 
36 
     | 
    
         
             
            end
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: rage-rb
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 1. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 1.10.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Roman Samoilov
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire:
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: exe
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date: 2024- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2024-09-16 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: thor
         
     | 
| 
         @@ -44,14 +44,14 @@ dependencies: 
     | 
|
| 
       44 
44 
     | 
    
         
             
                requirements:
         
     | 
| 
       45 
45 
     | 
    
         
             
                - - "~>"
         
     | 
| 
       46 
46 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       47 
     | 
    
         
            -
                    version: ' 
     | 
| 
      
 47 
     | 
    
         
            +
                    version: '4.0'
         
     | 
| 
       48 
48 
     | 
    
         
             
              type: :runtime
         
     | 
| 
       49 
49 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       50 
50 
     | 
    
         
             
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       51 
51 
     | 
    
         
             
                requirements:
         
     | 
| 
       52 
52 
     | 
    
         
             
                - - "~>"
         
     | 
| 
       53 
53 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       54 
     | 
    
         
            -
                    version: ' 
     | 
| 
      
 54 
     | 
    
         
            +
                    version: '4.0'
         
     | 
| 
       55 
55 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       56 
56 
     | 
    
         
             
              name: zeitwerk
         
     | 
| 
       57 
57 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
         @@ -80,6 +80,20 @@ dependencies: 
     | 
|
| 
       80 
80 
     | 
    
         
             
                - - "~>"
         
     | 
| 
       81 
81 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       82 
82 
     | 
    
         
             
                    version: '2.1'
         
     | 
| 
      
 83 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 84 
     | 
    
         
            +
              name: rake
         
     | 
| 
      
 85 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 86 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 87 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 88 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 89 
     | 
    
         
            +
                    version: '12.0'
         
     | 
| 
      
 90 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 91 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 92 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 93 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 94 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 95 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 96 
     | 
    
         
            +
                    version: '12.0'
         
     | 
| 
       83 
97 
     | 
    
         
             
            description:
         
     | 
| 
       84 
98 
     | 
    
         
             
            email:
         
     | 
| 
       85 
99 
     | 
    
         
             
            - rsamoi@icloud.com
         
     | 
| 
         @@ -145,6 +159,7 @@ files: 
     | 
|
| 
       145 
159 
     | 
    
         
             
            - lib/rage/session.rb
         
     | 
| 
       146 
160 
     | 
    
         
             
            - lib/rage/setup.rb
         
     | 
| 
       147 
161 
     | 
    
         
             
            - lib/rage/sidekiq_session.rb
         
     | 
| 
      
 162 
     | 
    
         
            +
            - lib/rage/tasks.rb
         
     | 
| 
       148 
163 
     | 
    
         
             
            - lib/rage/templates/Gemfile
         
     | 
| 
       149 
164 
     | 
    
         
             
            - lib/rage/templates/Rakefile
         
     | 
| 
       150 
165 
     | 
    
         
             
            - lib/rage/templates/app-controllers-application_controller.rb
         
     | 
| 
         @@ -155,8 +170,16 @@ files: 
     | 
|
| 
       155 
170 
     | 
    
         
             
            - lib/rage/templates/config-initializers-.keep
         
     | 
| 
       156 
171 
     | 
    
         
             
            - lib/rage/templates/config-routes.rb
         
     | 
| 
       157 
172 
     | 
    
         
             
            - lib/rage/templates/config.ru
         
     | 
| 
      
 173 
     | 
    
         
            +
            - lib/rage/templates/db-templates/app-models-application_record.rb
         
     | 
| 
      
 174 
     | 
    
         
            +
            - lib/rage/templates/db-templates/db-seeds.rb
         
     | 
| 
      
 175 
     | 
    
         
            +
            - lib/rage/templates/db-templates/mysql/config-database.yml
         
     | 
| 
      
 176 
     | 
    
         
            +
            - lib/rage/templates/db-templates/postgresql/config-database.yml
         
     | 
| 
      
 177 
     | 
    
         
            +
            - lib/rage/templates/db-templates/sqlite3/config-database.yml
         
     | 
| 
      
 178 
     | 
    
         
            +
            - lib/rage/templates/db-templates/trilogy/config-database.yml
         
     | 
| 
       158 
179 
     | 
    
         
             
            - lib/rage/templates/lib-.keep
         
     | 
| 
      
 180 
     | 
    
         
            +
            - lib/rage/templates/lib-tasks-.keep
         
     | 
| 
       159 
181 
     | 
    
         
             
            - lib/rage/templates/log-.keep
         
     | 
| 
      
 182 
     | 
    
         
            +
            - lib/rage/templates/model-template/model.rb
         
     | 
| 
       160 
183 
     | 
    
         
             
            - lib/rage/templates/public-.keep
         
     | 
| 
       161 
184 
     | 
    
         
             
            - lib/rage/uploaded_file.rb
         
     | 
| 
       162 
185 
     | 
    
         
             
            - lib/rage/version.rb
         
     |