rage-rb 1.17.1 → 1.19.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.
data/lib/rage-rb.rb CHANGED
@@ -6,67 +6,115 @@ require "iodine"
6
6
  require "pathname"
7
7
 
8
8
  module Rage
9
+ # Builds the Rage application with the configured middlewares.
9
10
  def self.application
10
11
  with_middlewares(Application.new(__router), config.middleware.middlewares)
11
12
  end
12
13
 
14
+ # Builds the Rage application which delegates Rails requests to `Rails.application`.
13
15
  def self.multi_application
14
16
  Rage::Router::Util::Cascade.new(application, Rails.application)
15
17
  end
16
18
 
19
+ # Shorthand to access {Rage::Cable Rage::Cable}.
20
+ # @return [Rage::Cable]
17
21
  def self.cable
18
22
  Rage::Cable
19
23
  end
20
24
 
25
+ # Shorthand to access {Rage::OpenAPI Rage::OpenAPI}.
26
+ # @return [Rage::OpenAPI]
21
27
  def self.openapi
22
28
  Rage::OpenAPI
23
29
  end
24
30
 
31
+ # Shorthand to access {Rage::Deferred Rage::Deferred}.
32
+ # @return [Rage::Deferred]
25
33
  def self.deferred
26
34
  Rage::Deferred
27
35
  end
28
36
 
37
+ # Shorthand to access {Rage::Events Rage::Events}.
38
+ # @return [Rage::Events]
39
+ def self.events
40
+ Rage::Events
41
+ end
42
+
43
+ # Configure routes for the Rage application.
44
+ # @return [Rage::Router::DSL::Handler]
45
+ # @example
46
+ # Rage.routes.draw do
47
+ # root to: "users#index"
48
+ # end
29
49
  def self.routes
30
50
  Rage::Router::DSL.new(__router)
31
51
  end
32
52
 
53
+ # @private
33
54
  def self.__router
34
55
  @__router ||= Rage::Router::Backend.new
35
56
  end
36
57
 
58
+ # @private
59
+ def self.__log_processor
60
+ @__log_processor ||= Rage::LogProcessor.new
61
+ end
62
+
63
+ # Access the Rage configuration.
64
+ # @return [Rage::Configuration] the Rage configuration instance.
37
65
  def self.config
38
66
  @config ||= Rage::Configuration.new
39
67
  end
40
68
 
69
+ # Configure Rage using a block.
70
+ # @example
71
+ # Rage.configure do |config|
72
+ # config.log_level = :debug
73
+ # end
41
74
  def self.configure(&)
42
75
  config.instance_eval(&)
43
76
  config.__finalize
44
77
  end
45
78
 
79
+ # Access the current Rage environment.
80
+ # @return [Rage::Env] the Rage environment instance
81
+ # @example
82
+ # if Rage.env.development?
83
+ # puts "Running in development mode"
84
+ # end
46
85
  def self.env
47
86
  @__env ||= Rage::Env.new(ENV["RAGE_ENV"] || ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development")
48
87
  end
49
88
 
89
+ # Access the current Gem groups based on the Rage environment.
50
90
  def self.groups
51
91
  [:default, Rage.env.to_sym]
52
92
  end
53
93
 
94
+ # Access the root path of the Rage application.
95
+ # @return [Pathname] the root path
54
96
  def self.root
55
97
  @root ||= Pathname.new(".").expand_path
56
98
  end
57
99
 
100
+ # Access the Rage logger.
101
+ # @return [Rage::Logger] the Rage logger instance
58
102
  def self.logger
59
103
  @logger ||= config.logger
60
104
  end
61
105
 
106
+ # Load middlewares into the Rage application.
107
+ # @deprecated This method is deprecated and has been merged into `Rage.application`.
62
108
  def self.load_middlewares(_)
63
109
  puts "`Rage.load_middlewares` is deprecated and has been merged into `Rage.application`. Please remove this call."
64
110
  end
65
111
 
112
+ # @private
66
113
  def self.code_loader
67
114
  @code_loader ||= Rage::CodeLoader.new
68
115
  end
69
116
 
117
+ # @private
70
118
  def self.patch_active_record_connection_pool
71
119
  patch = proc do
72
120
  is_connected = ActiveRecord::Base.connection_pool rescue false
@@ -90,6 +138,7 @@ module Rage
90
138
  end
91
139
  end
92
140
 
141
+ # Load Rake tasks for the Rage application.
93
142
  def self.load_tasks
94
143
  Rage::Tasks.init
95
144
  end
@@ -135,9 +184,11 @@ module Rage
135
184
  autoload :Cable, "rage/cable/cable"
136
185
  autoload :OpenAPI, "rage/openapi/openapi"
137
186
  autoload :Deferred, "rage/deferred/deferred"
187
+ autoload :Events, "rage/events/events"
138
188
  end
139
189
 
140
190
  module RageController
141
191
  end
142
192
 
143
193
  require_relative "rage/env"
194
+ require_relative "rage/internal"
data/rage.gemspec CHANGED
@@ -33,4 +33,5 @@ Gem::Specification.new do |spec|
33
33
  spec.add_dependency "zeitwerk", "~> 2.6"
34
34
  spec.add_dependency "rack-test", "~> 2.1"
35
35
  spec.add_dependency "rake", ">= 12.0"
36
+ spec.add_dependency "logger"
36
37
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rage-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.17.1
4
+ version: 1.19.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roman Samoilov
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-08-21 00:00:00.000000000 Z
10
+ date: 2025-12-03 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: thor
@@ -93,6 +93,20 @@ dependencies:
93
93
  - - ">="
94
94
  - !ruby/object:Gem::Version
95
95
  version: '12.0'
96
+ - !ruby/object:Gem::Dependency
97
+ name: logger
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ type: :runtime
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
96
110
  email:
97
111
  - rsamoi@icloud.com
98
112
  executables:
@@ -102,11 +116,11 @@ extra_rdoc_files: []
102
116
  files:
103
117
  - ".rspec"
104
118
  - ".yardopts"
119
+ - ARCHITECTURE.md
105
120
  - CHANGELOG.md
106
121
  - CODE_OF_CONDUCT.md
107
122
  - Gemfile
108
123
  - LICENSE.txt
109
- - OVERVIEW.md
110
124
  - README.md
111
125
  - Rakefile
112
126
  - exe/rage
@@ -130,18 +144,22 @@ files:
130
144
  - lib/rage/cookies.rb
131
145
  - lib/rage/deferred/backends/disk.rb
132
146
  - lib/rage/deferred/backends/nil.rb
147
+ - lib/rage/deferred/context.rb
133
148
  - lib/rage/deferred/deferred.rb
134
- - lib/rage/deferred/metadata.rb
135
149
  - lib/rage/deferred/proxy.rb
136
150
  - lib/rage/deferred/queue.rb
137
151
  - lib/rage/deferred/task.rb
138
152
  - lib/rage/env.rb
139
153
  - lib/rage/errors.rb
154
+ - lib/rage/events/events.rb
155
+ - lib/rage/events/subscriber.rb
140
156
  - lib/rage/ext/active_record/connection_pool.rb
141
157
  - lib/rage/ext/setup.rb
142
158
  - lib/rage/fiber.rb
143
159
  - lib/rage/fiber_scheduler.rb
144
160
  - lib/rage/hooks.rb
161
+ - lib/rage/internal.rb
162
+ - lib/rage/log_processor.rb
145
163
  - lib/rage/logger/json_formatter.rb
146
164
  - lib/rage/logger/logger.rb
147
165
  - lib/rage/logger/text_formatter.rb
data/OVERVIEW.md DELETED
@@ -1,83 +0,0 @@
1
- ### Table of Contents
2
-
3
- [API Workflow](#api-workflow)<br>
4
- [Executing Controller Actions](#executing-controller-actions)<br>
5
- [Cable Workflow](#cable-workflow)<br>
6
- [OpenAPI Workflow](#openapi-workflow)<br>
7
- [Design Principles](#design-principles)<br>
8
-
9
- ### API Workflow
10
-
11
- The following diagram describes some of Rage's internal components and the way they interact with each other:
12
-
13
- ![overview](https://github.com/rage-rb/rage/assets/2270393/0d45bbe3-622c-4b17-b8d8-552c567fecb3)
14
-
15
- ### Executing Controller Actions
16
-
17
- When `Rage::Router::DSL` parses the `config/routes.rb` file and calls the `Rage::Router::Backend` class, it registers actions and stores handler procs.
18
-
19
- Consider we have the following controller:
20
-
21
- ```ruby
22
- class UsersController < RageController::API
23
- before_action :find_user
24
- rescue_from ActiveRecord::RecordNotFound, with: :render_not_found
25
-
26
- def show
27
- render json: @user
28
- end
29
-
30
- private
31
-
32
- def find_user
33
- @user = User.find(params[:id])
34
- end
35
-
36
- def render_not_found(_)
37
- render status: :not_found
38
- end
39
- end
40
- ```
41
-
42
- Before processing requests to `UsersController#show`, Rage has to [register](https://github.com/rage-rb/rage/blob/master/lib/rage/controller/api.rb#L11) the show action. Registering means defining a new method that will look like this:
43
-
44
- ```ruby
45
- class UsersController
46
- def __run_show
47
- find_user
48
- show
49
- rescue ActiveRecord::RecordNotFound => e
50
- render_not_found(e)
51
- end
52
- end
53
- ```
54
-
55
- After that, Rage will create and store a handler proc that will look exactly like this:
56
-
57
- ```ruby
58
- ->(env, params) { UsersController.new(env, params).__run_show }
59
- ```
60
-
61
- All of this happens at boot time. Once the request comes in at runtime, Rage will only need to retrieve the handler proc defined earlier and call it.
62
-
63
- ### Cable Workflow
64
-
65
- The following diagram describes the components of a `Rage::Cable` application:
66
-
67
- ![cable](https://github.com/user-attachments/assets/86db2091-f93a-44f8-9512-c4701770d09e)
68
-
69
- ### OpenAPI Workflow
70
-
71
- The following diagram describes the flow of `Rage::OpenAPI`:
72
-
73
- <img width="800" src="https://github.com/user-attachments/assets/b4a87b1e-9a0f-4432-a3e9-0106ff546f3f" />
74
-
75
- ### Design Principles
76
-
77
- * **Lean Happy Path:** we try to execute as many operations as possible during server initialization to minimize workload during request processing. Additionally, new features should be designed to avoid impacting the framework performance for users who do not utilize those features.
78
-
79
- * **Performance Over Code Style:** we recognize the distinct requirements of framework and client code. Testability, readability, and maintainability are crucial for client code used in application development. Conversely, library code addresses different tasks and should be designed with different objectives. In library code, performance and abstraction to enable future modifications while maintaining backward compatibility take precedence over typical client code concerns, though testability and readability remain important.
80
-
81
- * **Rails Compatibility:** Rails compatibility is a key objective to ensure a seamless transition for developers. While it may not be feasible to replicate every method implemented in Rails, the framework should function in a familiar and expected manner.
82
-
83
- * **Single-Threaded Fiber-Based Approach:** each request is processed in a separate, isolated execution context (Fiber), pausing whenever it encounters blocking I/O. This single-threaded approach eliminates thread synchronization overhead, leading to enhanced performance and simplified code.
@@ -1,43 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- ##
4
- # Metadata for deferred tasks.
5
- # The class encapsulates the metadata associated with a deferred task, and allows to store it without modifying the task instance.
6
- #
7
- class Rage::Deferred::Metadata
8
- def self.build(task, args, kwargs)
9
- request_id = Thread.current[:rage_logger][:tags][0] if Thread.current[:rage_logger]
10
-
11
- [
12
- task,
13
- args.empty? ? nil : args,
14
- kwargs.empty? ? nil : kwargs,
15
- nil,
16
- request_id
17
- ]
18
- end
19
-
20
- def self.get_task(metadata)
21
- metadata[0]
22
- end
23
-
24
- def self.get_args(metadata)
25
- metadata[1]
26
- end
27
-
28
- def self.get_kwargs(metadata)
29
- metadata[2]
30
- end
31
-
32
- def self.get_attempts(metadata)
33
- metadata[3]
34
- end
35
-
36
- def self.get_request_id(metadata)
37
- metadata[4]
38
- end
39
-
40
- def self.inc_attempts(metadata)
41
- metadata[3] = metadata[3].to_i + 1
42
- end
43
- end