shed_machines 0.1.1-aarch64-linux
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 +7 -0
- data/CHANGELOG.md +42 -0
- data/LICENSE.txt +21 -0
- data/README.md +174 -0
- data/ext/shed_machines_native/extconf.rb +3 -0
- data/lib/shed_machines/version.rb +5 -0
- data/lib/shed_machines.rb +7 -0
- data/lib/shed_machines_native/shed_machines_native.so +0 -0
- data/sig/shed_machines.rbs +131 -0
- metadata +63 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 83fbc1a79847e47c4a3a4f4cd90bee30a57f330937cc392ea0beecaf06939935
|
|
4
|
+
data.tar.gz: 0f3ebbbd83afabf9b4cc5d571e3e6cd003c8476530be47d9c788d5967bc1d20b
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 833d4bad1d9ae81c55dd6c04db258869b2ac00940fc1c326802ed5a9087bf9a2e05a5b312a2a0d6b69744b258c96dd6c0c500b2eec631794df920d3cb7db562e
|
|
7
|
+
data.tar.gz: 7cffedc2849777b02c7ad01b31ed3eaaa40b2dbe0247a73553de56b6608950176f64800e0934983e7c7d083a632a0098b653957d85f2bfe8c400de0e4181676b
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.1.1](https://github.com/seuros/shed_machines/compare/shed_machines-v0.1.0...shed_machines/v0.1.1) (2026-11-01)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* adaptive concurrency limits and load shedding ([e07f0dc](https://github.com/seuros/shed_machines/commit/e07f0dca6cc3dc65a49757d5eda0b96256310c61))
|
|
9
|
+
* pass a rubygems OTP through the environment ([8a4d15b](https://github.com/seuros/shed_machines/commit/8a4d15bc46fed686dd67da5566b8d5c252de617c))
|
|
10
|
+
* Ruby gem and magnus FFI for the control loops ([b323351](https://github.com/seuros/shed_machines/commit/b323351d11a2ee01782e93cafe769a24e4485ed0))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* a configured CoDel duration goes through the same check as an observed one ([c424040](https://github.com/seuros/shed_machines/commit/c424040c95e419f88d20f06d19cd07bf5fba30f5))
|
|
16
|
+
* a source install can build, and a failed gem push fails the release ([4975e7f](https://github.com/seuros/shed_machines/commit/4975e7fcc39820ec681d79e8d0e3213878c61487))
|
|
17
|
+
* AIMD divided by zero, and both controllers saturated before dividing ([67006bd](https://github.com/seuros/shed_machines/commit/67006bdad51f9caef02594f042f2b5a5c7d34735))
|
|
18
|
+
* avoid re-entrant borrow and u32 clipping in shed control ([d4a1b09](https://github.com/seuros/shed_machines/commit/d4a1b0950e6de32bb2756f5ef183e649ff04d829))
|
|
19
|
+
* collect the built gems whatever depth the download puts them at ([7ffc2db](https://github.com/seuros/shed_machines/commit/7ffc2db96f97a1b30b3992b16d30dc45fd43f216))
|
|
20
|
+
* refuse a fractional call count instead of truncating it to zero ([869c3d8](https://github.com/seuros/shed_machines/commit/869c3d8988ae4e1be5924899466522053fa47981))
|
|
21
|
+
* reject durations and bounds the arithmetic cannot survive ([37edc6f](https://github.com/seuros/shed_machines/commit/37edc6f8849e9fff6192955cc41e910a930b3fcf))
|
|
22
|
+
* ship the core's test files so the packaged crate builds ([9a3e00d](https://github.com/seuros/shed_machines/commit/9a3e00dffffff31bbebfbaf6e9c57e2d21cea43e))
|
|
23
|
+
* the release tag carries the gem name, and the gate uses the aggregate output ([f0937ad](https://github.com/seuros/shed_machines/commit/f0937ad7ecbab770aaa81378c1035f80442291b7))
|
|
24
|
+
|
|
25
|
+
## 0.1.0
|
|
26
|
+
|
|
27
|
+
- Initial release.
|
|
28
|
+
- `ShedMachines::Aimd`: additive increase per saturated success, multiplicative
|
|
29
|
+
decrease on overload, with a configurable `kept / of` backoff fraction.
|
|
30
|
+
- `ShedMachines::Vegas`: TCP Vegas applied to a concurrency limit, steering by
|
|
31
|
+
the queue estimate drawn from the gap between current and best round-trip
|
|
32
|
+
time, with a configurable `alpha`/`beta` band.
|
|
33
|
+
- `ShedMachines::Codel`: controlled delay, shedding queued work by how long it
|
|
34
|
+
waited once the wait stays above target for a full interval, with sheds that
|
|
35
|
+
come faster as the inverse square root of how many have happened.
|
|
36
|
+
- `ShedMachines::Budget`: client-side adaptive throttling, reporting the
|
|
37
|
+
fraction of the next retry wave to drop rather than making the decision.
|
|
38
|
+
- Durations cross the Ruby boundary as seconds in Floats and are converted once
|
|
39
|
+
to nanoseconds; the control laws themselves are integer-only.
|
|
40
|
+
- `shed-machines` core crate: the four control laws in `no_std` Rust with zero
|
|
41
|
+
dependencies. Builds and lints clean on bare metal.
|
|
42
|
+
- RBS signatures for the whole public API.
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Abdelkader Boudih
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# ShedMachines 🌊
|
|
2
|
+
|
|
3
|
+
> **Adaptive concurrency limits and load shedding.** The escort that reads the
|
|
4
|
+
> convoy's own telemetry and says how wide the lane is, right now.
|
|
5
|
+
|
|
6
|
+
A fixed bulkhead is a guess that is wrong at every load except the one it was
|
|
7
|
+
tuned for. **AMS Jacobson** does not carry a tuned number. These four control
|
|
8
|
+
loops read what completed calls report and answer one question each: how many
|
|
9
|
+
calls may be in flight, whether this queued piece of work is still worth
|
|
10
|
+
running, and how much of the next retry wave to drop before it leaves the
|
|
11
|
+
process.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 🚀 Launch Sequence
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Add to your ship's Gemfile
|
|
19
|
+
gem 'shed_machines'
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Requires **Ruby 4.0+** and a Rust toolchain, or a platform gem.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## 🎯 Mission Brief
|
|
27
|
+
|
|
28
|
+
```ruby
|
|
29
|
+
require 'shed_machines'
|
|
30
|
+
|
|
31
|
+
control = ShedMachines::Vegas.new(limit: 10, min: 1, max: 200)
|
|
32
|
+
|
|
33
|
+
control.observe(rtt: 0.004, in_flight: 10, outcome: :ok)
|
|
34
|
+
control.limit # => 11
|
|
35
|
+
|
|
36
|
+
control.observe(rtt: 0.040, in_flight: 11, outcome: :ok)
|
|
37
|
+
control.limit # => 10
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The escort advises, it does not fire. Nothing here enforces anything. The
|
|
41
|
+
caller owns the semaphore, the queue and the dice.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## 🔩 The Native Extension Is Required
|
|
46
|
+
|
|
47
|
+
There is no pure-Ruby fallback and no switch to turn one on. `require
|
|
48
|
+
'shed_machines'` loads the extension, and fails if it is not there. A control
|
|
49
|
+
law with two implementations is a control law with two behaviours, and the whole
|
|
50
|
+
point of these four is that they are the same arithmetic everywhere: the gem is
|
|
51
|
+
a binding to the `shed-machines` crate in `ext/shed_machines_native/core`, which
|
|
52
|
+
is `no_std` with zero dependencies and also runs on bare metal. It needs Ruby
|
|
53
|
+
4.0 and a Rust toolchain, or a platform gem.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## 🎚️ Moving a Concurrency Limit
|
|
58
|
+
|
|
59
|
+
`Aimd` grows the limit by one whenever a saturated call succeeds, and keeps
|
|
60
|
+
three quarters of it on any overload. It needs no latency signal.
|
|
61
|
+
|
|
62
|
+
```ruby
|
|
63
|
+
control = ShedMachines::Aimd.new(limit: 10, min: 1, max: 100)
|
|
64
|
+
|
|
65
|
+
control.observe(rtt: 0.004, in_flight: 10, outcome: :ok) # saturated: grows
|
|
66
|
+
control.limit # => 11
|
|
67
|
+
|
|
68
|
+
control.observe(rtt: 0.004, in_flight: 11, outcome: :overload)
|
|
69
|
+
control.limit # => 8
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
`Vegas` infers queue depth from the gap between the current round-trip time and
|
|
73
|
+
the best one it has seen, because latency alone cannot tell a slow dependency
|
|
74
|
+
from a deep queue. It grows while fewer than `alpha` calls look queued, shrinks
|
|
75
|
+
above `beta`, and holds in between.
|
|
76
|
+
|
|
77
|
+
```ruby
|
|
78
|
+
control = ShedMachines::Vegas.new(limit: 10, min: 1, max: 200, alpha: 3, beta: 6)
|
|
79
|
+
control.best_rtt # => nil, until the first completed call
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Both take `outcome: :ok` or `outcome: :overload`, where overload means the call
|
|
83
|
+
timed out, was rejected, or otherwise says the dependency is loaded. Anything
|
|
84
|
+
else raises `ArgumentError`. Both clamp a starting limit into `min..max`, which
|
|
85
|
+
default to `LOWEST_FLOOR` and `DEFAULT_CEILING`.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## ⏱️ Shedding by Waiting Time
|
|
90
|
+
|
|
91
|
+
Queue length is the wrong signal, since a fast queue can be long and a stalled
|
|
92
|
+
one short. `Codel` watches how long work waited and sheds only once that stays
|
|
93
|
+
above target for a full interval, so a burst passes through and a standing queue
|
|
94
|
+
does not.
|
|
95
|
+
|
|
96
|
+
```ruby
|
|
97
|
+
queue = ShedMachines::Codel.new # 5 ms target, 100 ms interval
|
|
98
|
+
|
|
99
|
+
queue.admit(sojourn: 0.020, now: 0.000) # => :admit, the burst is tolerated
|
|
100
|
+
queue.admit(sojourn: 0.020, now: 0.150) # => :shed, it is a standing queue
|
|
101
|
+
queue.shedding? # => true
|
|
102
|
+
queue.admit(sojourn: 0.001, now: 0.200) # => :admit, and the state clears
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Successive sheds come faster, as the inverse square root of how many have
|
|
106
|
+
happened, so the control law converges instead of oscillating.
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## 🌀 Not Amplifying an Outage
|
|
111
|
+
|
|
112
|
+
A client that keeps retrying a failing dependency multiplies the load that broke
|
|
113
|
+
it. `Budget` tracks what the client asked for against what was accepted and
|
|
114
|
+
reports what fraction of the next wave to drop.
|
|
115
|
+
|
|
116
|
+
```ruby
|
|
117
|
+
budget = ShedMachines::Budget.new # each accept earns 2 requests
|
|
118
|
+
|
|
119
|
+
100.times { budget.requested.accepted }
|
|
120
|
+
budget.shed_probability # => 0.0
|
|
121
|
+
|
|
122
|
+
300.times { budget.requested }
|
|
123
|
+
budget.shed_probability # => 0.4987...
|
|
124
|
+
|
|
125
|
+
budget.decay # halves both counts
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
`shed_probability` is a fraction, not a decision, so nothing here needs a random
|
|
129
|
+
number generator.
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## 📐 Seconds In, Nanoseconds Inside
|
|
134
|
+
|
|
135
|
+
Every duration crosses this boundary as seconds in a `Float`, and is converted
|
|
136
|
+
once to nanoseconds. The control laws are integer-only on purpose: a limit, a
|
|
137
|
+
queue estimate and a backoff are counts, and counting in floats invites a
|
|
138
|
+
limiter that is 10.999999 calls wide.
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## 📊 Constants on the Instrument Panel
|
|
143
|
+
|
|
144
|
+
The Ruby constants mirror the crate's, with the same names and values.
|
|
145
|
+
|
|
146
|
+
| Constant | Value |
|
|
147
|
+
| ---------------------------------- | ----------- |
|
|
148
|
+
| `ShedMachines::LOWEST_FLOOR` | 1 |
|
|
149
|
+
| `ShedMachines::DEFAULT_CEILING` | 1000 |
|
|
150
|
+
| `Aimd::DEFAULT_BACKOFF_KEPT` | 3 |
|
|
151
|
+
| `Aimd::DEFAULT_BACKOFF_OF` | 4 |
|
|
152
|
+
| `Vegas::DEFAULT_ALPHA` | 3 |
|
|
153
|
+
| `Vegas::DEFAULT_BETA` | 6 |
|
|
154
|
+
| `Vegas::OVERLOAD_DIVISOR` | 2 |
|
|
155
|
+
| `Codel::DEFAULT_TARGET_NS` | 5_000_000 |
|
|
156
|
+
| `Codel::DEFAULT_INTERVAL_NS` | 100_000_000 |
|
|
157
|
+
| `Budget::DEFAULT_MULTIPLIER` | 2.0 |
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## 📡 Credits
|
|
162
|
+
|
|
163
|
+
**AMS Jacobson**, NCC-2012, *Jacobson*-class escort.
|
|
164
|
+
|
|
165
|
+
Named for Kathleen Nichols and Van Jacobson, *Controlling Queue Delay* (2012),
|
|
166
|
+
the paper that introduced controlled delay, CoDel, and argued that a queue
|
|
167
|
+
should be judged by how long work waits in it rather than by how much work is
|
|
168
|
+
in it.
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## License
|
|
173
|
+
|
|
174
|
+
MIT.
|
|
Binary file
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# Adaptive concurrency limits and load shedding. Every class here is defined by
|
|
2
|
+
# the native extension, which binds the `shed-machines` crate.
|
|
3
|
+
#
|
|
4
|
+
# Nothing here enforces anything: these are the control loops, and the caller
|
|
5
|
+
# owns the semaphore, the queue and the dice.
|
|
6
|
+
module ShedMachines
|
|
7
|
+
VERSION: String
|
|
8
|
+
|
|
9
|
+
# Nanoseconds in a second. Durations cross this boundary as seconds and move
|
|
10
|
+
# through the control laws as nanoseconds.
|
|
11
|
+
NS_PER_SECOND: Integer
|
|
12
|
+
|
|
13
|
+
# A limit of zero would wedge the caller shut, so one is the lowest floor that
|
|
14
|
+
# still makes progress.
|
|
15
|
+
LOWEST_FLOOR: Integer
|
|
16
|
+
|
|
17
|
+
# Arbitrary, and deliberately so: there is no principled default ceiling for
|
|
18
|
+
# an unknown dependency. Set it from what the pool behind it can take.
|
|
19
|
+
DEFAULT_CEILING: Integer
|
|
20
|
+
|
|
21
|
+
# How a completed call ended, from the limiter's point of view. `:overload`
|
|
22
|
+
# means it timed out, was rejected, or otherwise says the dependency is
|
|
23
|
+
# loaded. Anything else raises `ArgumentError`.
|
|
24
|
+
type outcome = :ok | :overload
|
|
25
|
+
|
|
26
|
+
# What to do with a piece of work that has been waiting.
|
|
27
|
+
type verdict = :admit | :shed
|
|
28
|
+
|
|
29
|
+
# Additive increase, multiplicative decrease: grows the limit by one whenever
|
|
30
|
+
# a saturated call succeeds, and keeps `kept / of` of it on any overload.
|
|
31
|
+
class Aimd
|
|
32
|
+
DEFAULT_BACKOFF_KEPT: Integer
|
|
33
|
+
DEFAULT_BACKOFF_OF: Integer
|
|
34
|
+
|
|
35
|
+
# `limit` outside `min..max` is pulled inside it.
|
|
36
|
+
def self.new: (
|
|
37
|
+
limit: Integer,
|
|
38
|
+
?min: Integer,
|
|
39
|
+
?max: Integer,
|
|
40
|
+
?kept: Integer,
|
|
41
|
+
?of: Integer
|
|
42
|
+
) -> instance
|
|
43
|
+
|
|
44
|
+
# Folds one completed call into the limit. `rtt` is in seconds, `in_flight`
|
|
45
|
+
# counts the calls in flight when this one started, including itself.
|
|
46
|
+
def observe: (rtt: Float, in_flight: Integer, outcome: outcome) -> self
|
|
47
|
+
|
|
48
|
+
# Calls allowed in flight right now.
|
|
49
|
+
def limit: () -> Integer
|
|
50
|
+
|
|
51
|
+
def inspect: () -> String
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# TCP Vegas applied to a concurrency limit: estimates how many calls are
|
|
55
|
+
# queued rather than working from the gap between the current round-trip time
|
|
56
|
+
# and the best one seen, then steers the limit to keep that estimate between
|
|
57
|
+
# `alpha` and `beta`.
|
|
58
|
+
class Vegas
|
|
59
|
+
DEFAULT_ALPHA: Integer
|
|
60
|
+
DEFAULT_BETA: Integer
|
|
61
|
+
OVERLOAD_DIVISOR: Integer
|
|
62
|
+
|
|
63
|
+
def self.new: (
|
|
64
|
+
limit: Integer,
|
|
65
|
+
?min: Integer,
|
|
66
|
+
?max: Integer,
|
|
67
|
+
?alpha: Integer,
|
|
68
|
+
?beta: Integer
|
|
69
|
+
) -> instance
|
|
70
|
+
|
|
71
|
+
def observe: (rtt: Float, in_flight: Integer, outcome: outcome) -> self
|
|
72
|
+
|
|
73
|
+
def limit: () -> Integer
|
|
74
|
+
|
|
75
|
+
# The best round-trip time seen so far in seconds, the stand-in for zero
|
|
76
|
+
# queueing. `nil` until the first completed call.
|
|
77
|
+
def best_rtt: () -> Float?
|
|
78
|
+
|
|
79
|
+
def inspect: () -> String
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Controlled delay: sheds by how long work waited rather than by how much of
|
|
83
|
+
# it there is, and only once the wait stays above target for a full interval.
|
|
84
|
+
class Codel
|
|
85
|
+
DEFAULT_TARGET_NS: Integer
|
|
86
|
+
DEFAULT_INTERVAL_NS: Integer
|
|
87
|
+
|
|
88
|
+
# Both in seconds, defaulting to the values the CoDel paper settled on.
|
|
89
|
+
def self.new: (?target: Float, ?interval: Float) -> instance
|
|
90
|
+
|
|
91
|
+
# `sojourn` is how long this work waited before being considered, `now` is
|
|
92
|
+
# the current time, both in seconds.
|
|
93
|
+
def admit: (sojourn: Float, now: Float) -> verdict
|
|
94
|
+
|
|
95
|
+
# The acceptable waiting time, in seconds.
|
|
96
|
+
def target: () -> Float
|
|
97
|
+
def interval: () -> Float
|
|
98
|
+
|
|
99
|
+
def shedding?: () -> bool
|
|
100
|
+
|
|
101
|
+
def inspect: () -> String
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Client-side adaptive throttling, so retries cannot amplify an outage.
|
|
105
|
+
class Budget
|
|
106
|
+
DEFAULT_MULTIPLIER: Float
|
|
107
|
+
|
|
108
|
+
# `multiplier` is how many requests each accepted one entitles the client
|
|
109
|
+
# to.
|
|
110
|
+
def self.new: (?multiplier: Float) -> instance
|
|
111
|
+
|
|
112
|
+
def requested: () -> self
|
|
113
|
+
|
|
114
|
+
def accepted: () -> self
|
|
115
|
+
|
|
116
|
+
# Halves both counts, so the budget forgets an outage instead of holding it
|
|
117
|
+
# against the dependency forever.
|
|
118
|
+
def decay: () -> self
|
|
119
|
+
|
|
120
|
+
def multiplier: () -> Float
|
|
121
|
+
def requests: () -> Integer
|
|
122
|
+
|
|
123
|
+
def accepts: () -> Integer
|
|
124
|
+
|
|
125
|
+
# The fraction of outbound work to drop locally, in `0.0..1.0`. A fraction
|
|
126
|
+
# rather than a decision: the caller owns the dice.
|
|
127
|
+
def shed_probability: () -> Float
|
|
128
|
+
|
|
129
|
+
def inspect: () -> String
|
|
130
|
+
end
|
|
131
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: shed_machines
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.1
|
|
5
|
+
platform: aarch64-linux
|
|
6
|
+
authors:
|
|
7
|
+
- Abdelkader Boudih
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-11-01 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description: 'AIMD and Vegas move a concurrency limit from what completed calls report,
|
|
14
|
+
CoDel sheds queued work by how long it waited, and a retry budget stops a client
|
|
15
|
+
from amplifying an outage. Bound to Ruby from the no_std shed-machines crate: the
|
|
16
|
+
control loops only, with the semaphore, the queue and the dice left to the caller.'
|
|
17
|
+
email:
|
|
18
|
+
- oss@seuros.com
|
|
19
|
+
executables: []
|
|
20
|
+
extensions: []
|
|
21
|
+
extra_rdoc_files: []
|
|
22
|
+
files:
|
|
23
|
+
- CHANGELOG.md
|
|
24
|
+
- LICENSE.txt
|
|
25
|
+
- README.md
|
|
26
|
+
- ext/shed_machines_native/extconf.rb
|
|
27
|
+
- lib/shed_machines.rb
|
|
28
|
+
- lib/shed_machines/version.rb
|
|
29
|
+
- lib/shed_machines_native/shed_machines_native.so
|
|
30
|
+
- sig/shed_machines.rbs
|
|
31
|
+
homepage: https://github.com/seuros/shed_machines
|
|
32
|
+
licenses:
|
|
33
|
+
- MIT
|
|
34
|
+
metadata:
|
|
35
|
+
source_code_uri: https://github.com/seuros/shed_machines
|
|
36
|
+
changelog_uri: https://github.com/seuros/shed_machines/blob/main/CHANGELOG.md
|
|
37
|
+
bug_tracker_uri: https://github.com/seuros/shed_machines/issues
|
|
38
|
+
rubygems_mfa_required: 'true'
|
|
39
|
+
cargo_crate_name: shed_machines_native
|
|
40
|
+
cargo_manifest_path: ext/shed_machines_native/ffi/Cargo.toml
|
|
41
|
+
post_install_message:
|
|
42
|
+
rdoc_options: []
|
|
43
|
+
require_paths:
|
|
44
|
+
- lib
|
|
45
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
46
|
+
requirements:
|
|
47
|
+
- - ">="
|
|
48
|
+
- !ruby/object:Gem::Version
|
|
49
|
+
version: '4.0'
|
|
50
|
+
- - "<"
|
|
51
|
+
- !ruby/object:Gem::Version
|
|
52
|
+
version: 4.1.dev
|
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
54
|
+
requirements:
|
|
55
|
+
- - ">="
|
|
56
|
+
- !ruby/object:Gem::Version
|
|
57
|
+
version: '0'
|
|
58
|
+
requirements: []
|
|
59
|
+
rubygems_version: 3.5.23
|
|
60
|
+
signing_key:
|
|
61
|
+
specification_version: 4
|
|
62
|
+
summary: Adaptive concurrency limits and load shedding for Ruby
|
|
63
|
+
test_files: []
|