rage-rb 1.19.2 → 1.20.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/.rspec +1 -0
- data/Appraisals +19 -0
- data/CHANGELOG.md +15 -1
- data/CODE_OF_CONDUCT.md +13 -17
- data/Gemfile +3 -0
- data/README.md +60 -63
- data/Rakefile +14 -0
- data/lib/rage/all.rb +3 -0
- data/lib/rage/cable/cable.rb +11 -7
- data/lib/rage/cable/channel.rb +6 -1
- data/lib/rage/cable/connection.rb +4 -0
- data/lib/rage/cable/router.rb +14 -9
- data/lib/rage/configuration.rb +235 -21
- data/lib/rage/controller/api.rb +49 -44
- data/lib/rage/deferred/context.rb +30 -2
- data/lib/rage/deferred/deferred.rb +18 -6
- data/lib/rage/deferred/metadata.rb +39 -0
- data/lib/rage/deferred/middleware_chain.rb +67 -0
- data/lib/rage/deferred/task.rb +45 -17
- data/lib/rage/events/events.rb +3 -3
- data/lib/rage/events/subscriber.rb +36 -25
- data/lib/rage/fiber.rb +33 -31
- data/lib/rage/fiber_scheduler.rb +6 -2
- data/lib/rage/logger/logger.rb +7 -1
- data/lib/rage/middleware/body_finalizer.rb +14 -0
- data/lib/rage/response.rb +10 -5
- data/lib/rage/rspec.rb +17 -17
- data/lib/rage/setup.rb +2 -2
- data/lib/rage/telemetry/handler.rb +131 -0
- data/lib/rage/telemetry/spans/await_fiber.rb +50 -0
- data/lib/rage/telemetry/spans/broadcast_cable_stream.rb +50 -0
- data/lib/rage/telemetry/spans/create_websocket_connection.rb +50 -0
- data/lib/rage/telemetry/spans/dispatch_fiber.rb +48 -0
- data/lib/rage/telemetry/spans/enqueue_deferred_task.rb +52 -0
- data/lib/rage/telemetry/spans/process_cable_action.rb +56 -0
- data/lib/rage/telemetry/spans/process_cable_connection.rb +56 -0
- data/lib/rage/telemetry/spans/process_controller_action.rb +56 -0
- data/lib/rage/telemetry/spans/process_deferred_task.rb +54 -0
- data/lib/rage/telemetry/spans/process_event_subscriber.rb +54 -0
- data/lib/rage/telemetry/spans/publish_event.rb +54 -0
- data/lib/rage/telemetry/spans/spawn_fiber.rb +50 -0
- data/lib/rage/telemetry/telemetry.rb +121 -0
- data/lib/rage/telemetry/tracer.rb +97 -0
- data/lib/rage/version.rb +1 -1
- data/rage.gemspec +4 -3
- metadata +38 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a730f86d3b220732b6359247b4a0f3a44d72dd80aef857553f9daabb530753e6
|
|
4
|
+
data.tar.gz: 68254c6dcad99882a9bd4996051ac35713cad21f62405de59b311f01afc77616
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 118c2ad29d1f3f2f91a8c2d153c020cc053b2e975ca876f3e0b50e18f2707a639193762c3cf2f7a25685b0b609bfa83225c19507d0f4b8f8ff4b7ca926026e51
|
|
7
|
+
data.tar.gz: 6c988a0e2bd16f12ad614c5e40fd4fb6d5441ad1adc0135253f52e4a971b3614fa00b5b5627d04bd37140aa55079e8bacd939970e7ac4f594dff929a6ef64be0
|
data/.rspec
CHANGED
data/Appraisals
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
appraise "active_record_7_0" do
|
|
2
|
+
gem "activerecord", "~> 7.0.0"
|
|
3
|
+
end
|
|
4
|
+
|
|
5
|
+
appraise "active_record_7_1" do
|
|
6
|
+
gem "activerecord", "~> 7.1.0"
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
appraise "active_record_7_2" do
|
|
10
|
+
gem "activerecord", "~> 7.2.0"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
appraise "active_record_8_0" do
|
|
14
|
+
gem "activerecord", "~> 8.0.0"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
appraise "active_record_8_1" do
|
|
18
|
+
gem "activerecord", "~> 8.1.0"
|
|
19
|
+
end
|
data/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
-
## [1.
|
|
3
|
+
## [1.20.0] - 2026-01-20
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Add `Rage::Telemetry` (#186).
|
|
8
|
+
- Add the `Response#status` method. (#191).
|
|
9
|
+
- [Deferred] Expose deferred metadata (#188).
|
|
10
|
+
- [Deferred] Support deferred middleware (#184).
|
|
11
|
+
- Ensure compatibility with `Rack::Events` (#180).
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
- Refactor the implementation of `rescue_from` in `Rage::Events` (#185).
|
|
16
|
+
|
|
17
|
+
## [1.19.2] - 2026-01-06
|
|
4
18
|
|
|
5
19
|
### Changed
|
|
6
20
|
|
data/CODE_OF_CONDUCT.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Our Pledge
|
|
4
4
|
|
|
5
|
-
We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
|
5
|
+
We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation.
|
|
6
6
|
|
|
7
7
|
We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
|
|
8
8
|
|
|
@@ -10,22 +10,19 @@ We pledge to act and interact in ways that contribute to an open, welcoming, div
|
|
|
10
10
|
|
|
11
11
|
Examples of behavior that contributes to a positive environment for our community include:
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
- Demonstrating empathy and kindness toward other people
|
|
14
|
+
- Being respectful of differing opinions, viewpoints, and experiences
|
|
15
|
+
- Giving and gracefully accepting constructive feedback
|
|
16
|
+
- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
|
|
17
|
+
- Focusing on what is best not just for us as individuals, but for the overall community
|
|
18
18
|
|
|
19
19
|
Examples of unacceptable behavior include:
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
address, without their explicit permission
|
|
27
|
-
* Other conduct which could reasonably be considered inappropriate in a
|
|
28
|
-
professional setting
|
|
21
|
+
- The use of sexualized language or imagery, and sexual attention or advances of any kind
|
|
22
|
+
- Trolling, insulting or derogatory comments, and personal or political attacks
|
|
23
|
+
- Public or private harassment
|
|
24
|
+
- Publishing others’ private information, such as a physical or email address, without their explicit permission
|
|
25
|
+
- Other conduct which could reasonably be considered inappropriate in a professional setting
|
|
29
26
|
|
|
30
27
|
## Enforcement Responsibilities
|
|
31
28
|
|
|
@@ -67,14 +64,13 @@ Community leaders will follow these Community Impact Guidelines in determining t
|
|
|
67
64
|
|
|
68
65
|
### 4. Permanent Ban
|
|
69
66
|
|
|
70
|
-
**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior,
|
|
67
|
+
**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
|
|
71
68
|
|
|
72
69
|
**Consequence**: A permanent ban from any sort of public interaction within the community.
|
|
73
70
|
|
|
74
71
|
## Attribution
|
|
75
72
|
|
|
76
|
-
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.
|
|
77
|
-
available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
|
73
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.1, available at https://www.contributor-covenant.org/version/2/1/code_of_conduct.html.
|
|
78
74
|
|
|
79
75
|
Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity).
|
|
80
76
|
|
data/Gemfile
CHANGED
|
@@ -12,6 +12,8 @@ gem "yard"
|
|
|
12
12
|
gem "rubocop", "~> 1.65.0", require: false
|
|
13
13
|
|
|
14
14
|
group :test do
|
|
15
|
+
gem "ostruct"
|
|
16
|
+
gem "benchmark"
|
|
15
17
|
gem "activesupport"
|
|
16
18
|
gem "http"
|
|
17
19
|
gem "pg"
|
|
@@ -23,4 +25,5 @@ group :test do
|
|
|
23
25
|
gem "websocket-client-simple"
|
|
24
26
|
gem "prism"
|
|
25
27
|
gem "redis-client"
|
|
28
|
+
gem "appraisal", "~> 2.5"
|
|
26
29
|
end
|
data/README.md
CHANGED
|
@@ -6,74 +6,66 @@
|
|
|
6
6
|

|
|
7
7
|

|
|
8
8
|
|
|
9
|
-
Rage is a high-performance framework
|
|
9
|
+
Rage is a high-performance Ruby web framework that combines the developer experience of Rails with the scalability of fiber-based concurrency. Designed for API-first applications, it allows you to handle massive traffic loads using standard synchronous Ruby code - no complex async/await syntax required.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
If you love Rails but need better performance for I/O-heavy workloads, Rage provides the perfect balance: familiar conventions, low overhead, and a commitment to stability.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
## Why Rage?
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
Building high-performance APIs in Ruby shouldn't mean abandoning the conventions you know. Rage gives you Rails-like controllers, routing, and patterns, but runs on **fiber-based concurrency** that makes your application naturally non-blocking. When your code waits on database queries, HTTP calls, or other I/O, Rage automatically handles thousands of other requests instead of sitting idle.
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
Rage was built to solve the performance and stability gaps that often drive teams to migrate away from Ruby, providing a modern engine that keeps the ecosystem competitive.
|
|
18
|
+
|
|
19
|
+
**Key capabilities:**
|
|
20
|
+
|
|
21
|
+
- **Rails compatibility** - Familiar controller API, routing DSL, and conventions. Migrate gradually or start fresh.
|
|
22
|
+
- **True concurrency** - Fiber-based architecture handles I/O without threads, locks, or async/await syntax. Your code looks synchronous but runs concurrently.
|
|
23
|
+
- **Zero-dependency WebSockets** - Action Cable-compatible real-time features that work out-of-the-box without Redis, even in multi-process mode.
|
|
24
|
+
- **Auto-generated OpenAPI** - Documentation generated from your controllers using simple comment tags.
|
|
25
|
+
- **In-process Background jobs** - A durable, persistent queue that runs inside your app process. No Redis or separate worker processes required.
|
|
26
|
+
- **Built-in Observability** - Track and measure application behavior with `Rage::Telemetry`. Integrate with external monitoring platforms or build custom observability solutions.
|
|
27
|
+
- **Stable and focused** - Our goal is that the task "Upgrade Rage" never appears in your ticketing system. We focus strictly on APIs, maintain long-term deprecation cycles, and ensure that most updates are as simple as a `bundle update`.
|
|
28
|
+
|
|
29
|
+
Rage is API-only by design. Modern applications benefit from clear separation between backend and frontend, and Rage focuses exclusively on doing APIs well.
|
|
18
30
|
|
|
19
31
|
## Installation
|
|
20
32
|
|
|
21
33
|
Install the gem:
|
|
34
|
+
|
|
22
35
|
```
|
|
23
36
|
$ gem install rage-rb
|
|
24
37
|
```
|
|
25
38
|
|
|
26
39
|
Create a new app:
|
|
40
|
+
|
|
27
41
|
```
|
|
28
42
|
$ rage new my_app
|
|
29
43
|
```
|
|
30
44
|
|
|
31
45
|
Switch to your new application and install dependencies:
|
|
46
|
+
|
|
32
47
|
```
|
|
33
48
|
$ cd my_app
|
|
34
49
|
$ bundle
|
|
35
50
|
```
|
|
36
51
|
|
|
37
52
|
Start up the server and visit http://localhost:3000.
|
|
53
|
+
|
|
38
54
|
```
|
|
39
55
|
$ rage s
|
|
40
56
|
```
|
|
41
57
|
|
|
42
58
|
Start coding!
|
|
43
59
|
|
|
44
|
-
##
|
|
45
|
-
|
|
46
|
-
This gem is designed to be a drop-in replacement for Rails in API mode. Public API is expected to fully match Rails.
|
|
47
|
-
|
|
48
|
-
A Rage application can operate in two modes:
|
|
49
|
-
|
|
50
|
-
* **Rails Mode**: Integrate Rage into an existing Rails application to improve throughput and better handle traffic spikes. For more information, see [Rails Integration](https://github.com/rage-rb/rage/wiki/Rails-integration).
|
|
51
|
-
* **Standalone Mode**: Build high-performance services with minimal setup using Rage. To get started, run `rage new --help` for more details.
|
|
52
|
-
|
|
53
|
-
Check out in-depth API docs for more information:
|
|
54
|
-
|
|
55
|
-
- [Controller API](https://rage-rb.pages.dev/RageController/API)
|
|
56
|
-
- [Routing API](https://rage-rb.pages.dev/Rage/Router/DSL/Handler)
|
|
57
|
-
- [Fiber API](https://rage-rb.pages.dev/Fiber)
|
|
58
|
-
- [Logger API](https://rage-rb.pages.dev/Rage/Logger)
|
|
59
|
-
- [Configuration API](https://rage-rb.pages.dev/Rage/Configuration)
|
|
60
|
-
|
|
61
|
-
Built-in middleware:
|
|
62
|
-
- [CORS](https://rage-rb.pages.dev/Rage/Cors)
|
|
63
|
-
- [RequestId](https://rage-rb.pages.dev/Rage/RequestId)
|
|
60
|
+
## How It Works
|
|
64
61
|
|
|
65
|
-
|
|
62
|
+
Rage runs each request in a separate fiber. When your code performs I/O operations - HTTP requests, database queries, file reads - the fiber automatically pauses, and Rage processes other requests. When the I/O completes, the fiber resumes exactly where it left off.
|
|
66
63
|
|
|
67
|
-
|
|
68
|
-
- [RSpec Integration](https://github.com/rage-rb/rage/wiki/RSpec-integration)
|
|
69
|
-
- [WebSockets Guide](https://github.com/rage-rb/rage/wiki/WebSockets-guide)
|
|
70
|
-
- [Background Tasks Guide](https://github.com/rage-rb/rage/wiki/Background-Tasks-Guide)
|
|
71
|
-
|
|
72
|
-
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
|
+
This happens transparently. You write normal Ruby code, and Rage handles the concurrency.
|
|
73
65
|
|
|
74
66
|
### Example
|
|
75
67
|
|
|
76
|
-
|
|
68
|
+
Here's a controller that fetches data from an external API:
|
|
77
69
|
|
|
78
70
|
```ruby
|
|
79
71
|
require "net/http"
|
|
@@ -98,9 +90,9 @@ class PagesController < RageController::API
|
|
|
98
90
|
end
|
|
99
91
|
```
|
|
100
92
|
|
|
101
|
-
|
|
93
|
+
This looks like a standard Rails controller, and it is - except during `Net::HTTP.get`, Rage automatically pauses this fiber and processes other requests. When the HTTP call completes, Rage resumes exactly where it left off. This happens automatically for HTTP requests, PostgreSQL, MySQL, and other I/O operations.
|
|
102
94
|
|
|
103
|
-
|
|
95
|
+
The routes are equally familiar:
|
|
104
96
|
|
|
105
97
|
```ruby
|
|
106
98
|
Rage.routes.draw do
|
|
@@ -108,9 +100,9 @@ Rage.routes.draw do
|
|
|
108
100
|
end
|
|
109
101
|
```
|
|
110
102
|
|
|
111
|
-
|
|
103
|
+
### Parallel Execution
|
|
112
104
|
|
|
113
|
-
|
|
105
|
+
Need to make multiple I/O calls? Use `Fiber.await` to run them concurrently:
|
|
114
106
|
|
|
115
107
|
```ruby
|
|
116
108
|
require "net/http"
|
|
@@ -127,11 +119,31 @@ class PagesController < RageController::API
|
|
|
127
119
|
end
|
|
128
120
|
```
|
|
129
121
|
|
|
130
|
-
|
|
122
|
+
Instead of waiting for each request sequentially, Rage executes them concurrently and waits for all to complete.
|
|
123
|
+
|
|
124
|
+
## Two Ways to Use Rage
|
|
125
|
+
|
|
126
|
+
**Standalone**: Create new services with `rage new`. You get a clean project structure, CLI tools, and everything needed to build high-performance APIs from scratch.
|
|
127
|
+
|
|
128
|
+
**Rails Integration**: Add Rage to existing Rails applications for gradual migration. Use Rage for new endpoints or high-traffic routes while keeping the rest of your Rails app unchanged. See the [Rails Integration guide](https://rage-rb.dev/docs/rails) for details.
|
|
129
|
+
|
|
130
|
+
## Documentation
|
|
131
|
+
|
|
132
|
+
- [Getting Started](https://rage-rb.dev/docs/intro/) - Core concepts and setup
|
|
133
|
+
- [Controllers](https://rage-rb.dev/docs/controllers/) - Request handling and callbacks
|
|
134
|
+
- [Routing](https://rage-rb.dev/docs/routing/) - RESTful routes and namespaces
|
|
135
|
+
- [WebSockets](https://rage-rb.dev/docs/websockets/) - Real-time communication
|
|
136
|
+
- [OpenAPI](https://rage-rb.dev/docs/openapi/) - Auto-generated documentation
|
|
137
|
+
- [Background Jobs](https://rage-rb.dev/docs/deferred/) - In-process queue system
|
|
138
|
+
- [API Reference](https://rage-rb.dev/api/) - Detailed API documentation
|
|
139
|
+
|
|
140
|
+
For contributors, check the [architecture doc](https://github.com/rage-rb/rage/blob/main/ARCHITECTURE.md) to understand how Rage's components work together.
|
|
131
141
|
|
|
132
|
-
##
|
|
142
|
+
## Performance
|
|
133
143
|
|
|
134
|
-
|
|
144
|
+
Rage's fiber-based architecture delivers high throughput with minimal overhead. By stripping away the "framework tax", Rage gives your team more leeway to write slow-but-maintainable Ruby code without compromising the end-user experience.
|
|
145
|
+
|
|
146
|
+
#### Simple JSON responses
|
|
135
147
|
|
|
136
148
|
```ruby
|
|
137
149
|
class BenchmarksController < ApplicationController
|
|
@@ -141,13 +153,12 @@ class BenchmarksController < ApplicationController
|
|
|
141
153
|
end
|
|
142
154
|
```
|
|
143
155
|
|
|
144
|
-

|
|
145
157
|
|
|
146
|
-
#### Waiting on I/O
|
|
147
158
|
|
|
148
|
-
|
|
149
|
-
require "net/http"
|
|
159
|
+
#### I/O-bound operations
|
|
150
160
|
|
|
161
|
+
```ruby
|
|
151
162
|
class BenchmarksController < ApplicationController
|
|
152
163
|
def index
|
|
153
164
|
Net::HTTP.get(URI("<endpoint-that-responds-in-one-second>"))
|
|
@@ -156,9 +167,9 @@ class BenchmarksController < ApplicationController
|
|
|
156
167
|
end
|
|
157
168
|
```
|
|
158
169
|
|
|
159
|
-

|
|
160
171
|
|
|
161
|
-
####
|
|
172
|
+
#### Database Queries
|
|
162
173
|
|
|
163
174
|
```ruby
|
|
164
175
|
class BenchmarksController < ApplicationController
|
|
@@ -168,21 +179,7 @@ class BenchmarksController < ApplicationController
|
|
|
168
179
|
end
|
|
169
180
|
```
|
|
170
181
|
|
|
171
|
-

|
|
186
183
|
|
|
187
184
|
## Development
|
|
188
185
|
|
|
@@ -192,7 +189,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
|
192
189
|
|
|
193
190
|
## Contributing
|
|
194
191
|
|
|
195
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/rage-rb/rage. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/rage-rb/rage/blob/
|
|
192
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/rage-rb/rage. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/rage-rb/rage/blob/main/CODE_OF_CONDUCT.md).
|
|
196
193
|
|
|
197
194
|
## License
|
|
198
195
|
|
|
@@ -200,4 +197,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
|
200
197
|
|
|
201
198
|
## Code of Conduct
|
|
202
199
|
|
|
203
|
-
Everyone interacting in the Rage project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/rage-rb/rage/blob/
|
|
200
|
+
Everyone interacting in the Rage project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/rage-rb/rage/blob/main/CODE_OF_CONDUCT.md).
|
data/Rakefile
CHANGED
|
@@ -6,3 +6,17 @@ require "rspec/core/rake_task"
|
|
|
6
6
|
RSpec::Core::RakeTask.new(:spec)
|
|
7
7
|
|
|
8
8
|
task default: :spec
|
|
9
|
+
|
|
10
|
+
task :appraise do |_, args|
|
|
11
|
+
ext_versions = `appraisal list`.split("\n")
|
|
12
|
+
|
|
13
|
+
# Since we want to test against the main branch separately, we remove it from the list.
|
|
14
|
+
ext_versions.reject! { |version| version.end_with?("_head") }
|
|
15
|
+
|
|
16
|
+
ext_versions.each do |ext_version|
|
|
17
|
+
puts ">> Appraising #{ext_version}"
|
|
18
|
+
|
|
19
|
+
gem_name = ext_version.sub(/_\d+(_\d+)*$/, "")
|
|
20
|
+
system "bundle exec appraisal #{ext_version} rspec spec/ext/#{gem_name}/"
|
|
21
|
+
end
|
|
22
|
+
end
|
data/lib/rage/all.rb
CHANGED
|
@@ -33,6 +33,9 @@ require_relative "middleware/fiber_wrapper"
|
|
|
33
33
|
require_relative "middleware/cors"
|
|
34
34
|
require_relative "middleware/reloader"
|
|
35
35
|
require_relative "middleware/request_id"
|
|
36
|
+
require_relative "middleware/body_finalizer"
|
|
37
|
+
|
|
38
|
+
require_relative "telemetry/telemetry"
|
|
36
39
|
|
|
37
40
|
if defined?(Sidekiq)
|
|
38
41
|
require_relative "sidekiq_session"
|
data/lib/rage/cable/cable.rb
CHANGED
|
@@ -43,11 +43,13 @@ module Rage::Cable
|
|
|
43
43
|
accept_response = [0, __protocol.protocol_definition, []]
|
|
44
44
|
|
|
45
45
|
application = ->(env) do
|
|
46
|
-
|
|
47
|
-
env["rack.upgrade"]
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
46
|
+
Rage::Telemetry.tracer.span_cable_websocket_handshake(env:) do
|
|
47
|
+
if env["rack.upgrade?"] == :websocket
|
|
48
|
+
env["rack.upgrade"] = handler
|
|
49
|
+
accept_response
|
|
50
|
+
else
|
|
51
|
+
[426, { "connection" => "upgrade", "upgrade" => "websocket" }, []]
|
|
52
|
+
end
|
|
51
53
|
end
|
|
52
54
|
end
|
|
53
55
|
|
|
@@ -133,8 +135,10 @@ module Rage::Cable
|
|
|
133
135
|
# @example
|
|
134
136
|
# Rage.cable.broadcast("chat", { message: "A new member has joined!" })
|
|
135
137
|
def self.broadcast(stream, data)
|
|
136
|
-
|
|
137
|
-
|
|
138
|
+
Rage::Telemetry.tracer.span_cable_stream_broadcast(stream:) do
|
|
139
|
+
__protocol.broadcast(stream, data)
|
|
140
|
+
__adapter&.publish(stream, data)
|
|
141
|
+
end
|
|
138
142
|
|
|
139
143
|
true
|
|
140
144
|
end
|
data/lib/rage/cable/channel.rb
CHANGED
|
@@ -372,7 +372,9 @@ class Rage::Cable::Channel
|
|
|
372
372
|
|
|
373
373
|
# @private
|
|
374
374
|
def __run_action(action_name, data = nil)
|
|
375
|
-
|
|
375
|
+
Rage::Telemetry.tracer.span_cable_action_process(channel: self, action: action_name, data:) do
|
|
376
|
+
self.class.__prepared_actions[action_name].call(self, data)
|
|
377
|
+
end
|
|
376
378
|
end
|
|
377
379
|
|
|
378
380
|
# @private
|
|
@@ -382,6 +384,9 @@ class Rage::Cable::Channel
|
|
|
382
384
|
@__identified_by = identified_by
|
|
383
385
|
end
|
|
384
386
|
|
|
387
|
+
# @private
|
|
388
|
+
attr_reader :__connection
|
|
389
|
+
|
|
385
390
|
# Get the params hash passed in during the subscription process.
|
|
386
391
|
#
|
|
387
392
|
# @return [Hash{Symbol=>String,Array,Hash,Numeric,NilClass,TrueClass,FalseClass}]
|
data/lib/rage/cable/router.rb
CHANGED
|
@@ -14,14 +14,18 @@ class Rage::Cable::Router
|
|
|
14
14
|
# @return [true] if the connection was accepted
|
|
15
15
|
# @return [false] if the connection was rejected
|
|
16
16
|
def process_connection(connection)
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
env = connection.env
|
|
18
|
+
|
|
19
|
+
cable_connection = @connection_class.new(env)
|
|
20
|
+
Rage::Telemetry.tracer.span_cable_connection_process(connection: cable_connection, action: :connect, env:) do
|
|
21
|
+
cable_connection.connect
|
|
22
|
+
end
|
|
19
23
|
|
|
20
24
|
if cable_connection.rejected?
|
|
21
25
|
Rage.logger.debug { "An unauthorized connection attempt was rejected" }
|
|
22
26
|
else
|
|
23
|
-
|
|
24
|
-
|
|
27
|
+
env["rage.identified_by"] = cable_connection.__identified_by_map
|
|
28
|
+
env["rage.cable"] = {}
|
|
25
29
|
end
|
|
26
30
|
|
|
27
31
|
!cable_connection.rejected?
|
|
@@ -105,12 +109,15 @@ class Rage::Cable::Router
|
|
|
105
109
|
#
|
|
106
110
|
# @param connection [Rage::Cable::WebSocketConnection] the connection object
|
|
107
111
|
def process_disconnection(connection)
|
|
108
|
-
connection.env
|
|
112
|
+
env = connection.env
|
|
113
|
+
|
|
114
|
+
env["rage.cable"]&.each do |_, channel|
|
|
109
115
|
channel.__run_action(:unsubscribed)
|
|
110
116
|
end
|
|
111
117
|
|
|
112
|
-
|
|
113
|
-
|
|
118
|
+
cable_connection = @connection_class.new(env, env["rage.identified_by"])
|
|
119
|
+
|
|
120
|
+
Rage::Telemetry.tracer.span_cable_connection_process(connection: cable_connection, action: :disconnect, env:) do
|
|
114
121
|
cable_connection.disconnect
|
|
115
122
|
end
|
|
116
123
|
end
|
|
@@ -132,7 +139,5 @@ class Rage::Cable::Router
|
|
|
132
139
|
puts "WARNING: Could not find the RageCable connection class! All connections will be accepted by default."
|
|
133
140
|
Rage::Cable::Connection
|
|
134
141
|
end
|
|
135
|
-
|
|
136
|
-
@connection_can_disconnect = @connection_class.method_defined?(:disconnect)
|
|
137
142
|
end
|
|
138
143
|
end
|