standard_circuit 0.5.0 → 0.6.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 +16 -0
- data/README.md +9 -0
- data/lib/standard_circuit/runner.rb +15 -0
- data/lib/standard_circuit/version.rb +1 -1
- metadata +8 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 195e01d912e93d7bf158cafd091aab7ab27571994e9d4c2953d0a39b76c92d71
|
|
4
|
+
data.tar.gz: 880f2b881ada6a92660c8c26c1c2b49abf2ea283411606a7131c9cf1af8bd75f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4706259801d563a2b60183691ad7c4ae935face858318e358d4e3bd5459c4b2eee097da52c8cb4748c7726883455f96a1416a23cde8b0123d172207d2f64b373
|
|
7
|
+
data.tar.gz: 05f1578d83f4bdbc34d310350570322bf4cd357d24d50e07874bed2e34019d33bb3cf0f396e49cf9a598797700aef34d3182b98c730d4a25e737f3f083ad6e80
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.6.0] - 2026-10-22
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **Zero-argument fallback lambdas no longer crash when the circuit opens.**
|
|
15
|
+
A fallback is called with the error (or `nil` when forced open), so a
|
|
16
|
+
`fallback: -> { ... }` raised `ArgumentError` at exactly the moment the
|
|
17
|
+
circuit opened, the case the fallback exists for. Such lambdas are now called
|
|
18
|
+
without the argument. Fallbacks that take the error, and procs, are
|
|
19
|
+
unchanged. Zero-arity `Method` fallbacks are accepted the same way.
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- **Requires Rails 8.1** (`railties`, `actionmailer`, `actionpack` `>= 8.1`,
|
|
24
|
+
was `>= 8.0`). Every consumer app runs 8.1; 8.0 was never exercised in CI.
|
|
25
|
+
|
|
10
26
|
## [0.5.0] - 2026-09-24
|
|
11
27
|
|
|
12
28
|
**Breaking.** Removes everything 0.4 deprecated. Behaviour of everything that remains is unchanged, including 0.4.2's `mailer_retry` (exhaustion reports, then re-raises so the job dead-letters).
|
data/README.md
CHANGED
|
@@ -54,8 +54,17 @@ end
|
|
|
54
54
|
StandardCircuit.run(:stripe) do
|
|
55
55
|
Stripe::PaymentIntent.create(amount:, currency:)
|
|
56
56
|
end
|
|
57
|
+
|
|
58
|
+
# with a fallback, returned instead of raising while the circuit is open
|
|
59
|
+
StandardCircuit.run(:analytics, fallback: -> { nil }) do
|
|
60
|
+
Analytics.track(event)
|
|
61
|
+
end
|
|
57
62
|
```
|
|
58
63
|
|
|
64
|
+
A fallback may take the error (`->(error) { ... }`: the error the block raised,
|
|
65
|
+
or `nil` once the circuit is open, since the block then never runs) or take
|
|
66
|
+
nothing (`-> { ... }`, or a zero-arity `method(...)`); all are called correctly.
|
|
67
|
+
|
|
59
68
|
## Error taxonomies
|
|
60
69
|
|
|
61
70
|
`tracked_errors` decide what counts toward tripping a circuit; `skipped_errors` are re-raised without counting (and win over `tracked_errors` when a class matches both). `StandardCircuit::ErrorTaxonomies::<Adapter>.tracked` combines `NetworkErrors.defaults` with the adapter's server-side errors for `Stripe`, `Smtp`, `Aws`, `Faraday`, and `Postmark`; `StandardCircuit::AdapterErrors::<Adapter>.caller_errors` lists the adapter's caller-side (4xx-style) errors.
|
|
@@ -12,6 +12,7 @@ module StandardCircuit
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def run(name, fallback: nil, &block)
|
|
15
|
+
fallback = accept_error_argument(fallback)
|
|
15
16
|
forced = @forced_states[name.to_sym]
|
|
16
17
|
return run_forced_open(name, fallback) if forced == :open
|
|
17
18
|
return yield if forced == :closed
|
|
@@ -73,6 +74,20 @@ module StandardCircuit
|
|
|
73
74
|
|
|
74
75
|
private
|
|
75
76
|
|
|
77
|
+
# A fallback is called with one argument: the error, or nil when the
|
|
78
|
+
# circuit is forced open. A zero-argument lambda (`-> { ... }`, the
|
|
79
|
+
# natural way to write "return this instead") raises ArgumentError on that
|
|
80
|
+
# call, so the fallback would crash at exactly the moment the circuit
|
|
81
|
+
# opens. Accept it, and a zero-arity Method (`fallback: method(:degraded)`),
|
|
82
|
+
# by calling it without the argument. Procs, and callables that take the
|
|
83
|
+
# error, are passed through unchanged.
|
|
84
|
+
def accept_error_argument(fallback)
|
|
85
|
+
strict = fallback.is_a?(Method) || (fallback.is_a?(Proc) && fallback.lambda?)
|
|
86
|
+
return fallback unless strict && fallback.arity.zero?
|
|
87
|
+
|
|
88
|
+
->(_error) { fallback.call }
|
|
89
|
+
end
|
|
90
|
+
|
|
76
91
|
def execute(name, fallback, &block)
|
|
77
92
|
started_at = monotonic_now
|
|
78
93
|
light = light_for(name)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: standard_circuit
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jaryl Sim
|
|
@@ -57,42 +57,42 @@ dependencies:
|
|
|
57
57
|
requirements:
|
|
58
58
|
- - ">="
|
|
59
59
|
- !ruby/object:Gem::Version
|
|
60
|
-
version: '8.
|
|
60
|
+
version: '8.1'
|
|
61
61
|
type: :runtime
|
|
62
62
|
prerelease: false
|
|
63
63
|
version_requirements: !ruby/object:Gem::Requirement
|
|
64
64
|
requirements:
|
|
65
65
|
- - ">="
|
|
66
66
|
- !ruby/object:Gem::Version
|
|
67
|
-
version: '8.
|
|
67
|
+
version: '8.1'
|
|
68
68
|
- !ruby/object:Gem::Dependency
|
|
69
69
|
name: actionmailer
|
|
70
70
|
requirement: !ruby/object:Gem::Requirement
|
|
71
71
|
requirements:
|
|
72
72
|
- - ">="
|
|
73
73
|
- !ruby/object:Gem::Version
|
|
74
|
-
version: '8.
|
|
74
|
+
version: '8.1'
|
|
75
75
|
type: :runtime
|
|
76
76
|
prerelease: false
|
|
77
77
|
version_requirements: !ruby/object:Gem::Requirement
|
|
78
78
|
requirements:
|
|
79
79
|
- - ">="
|
|
80
80
|
- !ruby/object:Gem::Version
|
|
81
|
-
version: '8.
|
|
81
|
+
version: '8.1'
|
|
82
82
|
- !ruby/object:Gem::Dependency
|
|
83
83
|
name: actionpack
|
|
84
84
|
requirement: !ruby/object:Gem::Requirement
|
|
85
85
|
requirements:
|
|
86
86
|
- - ">="
|
|
87
87
|
- !ruby/object:Gem::Version
|
|
88
|
-
version: '8.
|
|
88
|
+
version: '8.1'
|
|
89
89
|
type: :runtime
|
|
90
90
|
prerelease: false
|
|
91
91
|
version_requirements: !ruby/object:Gem::Requirement
|
|
92
92
|
requirements:
|
|
93
93
|
- - ">="
|
|
94
94
|
- !ruby/object:Gem::Version
|
|
95
|
-
version: '8.
|
|
95
|
+
version: '8.1'
|
|
96
96
|
- !ruby/object:Gem::Dependency
|
|
97
97
|
name: brakeman
|
|
98
98
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -201,7 +201,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
201
201
|
- !ruby/object:Gem::Version
|
|
202
202
|
version: '0'
|
|
203
203
|
requirements: []
|
|
204
|
-
rubygems_version: 4.0.
|
|
204
|
+
rubygems_version: 4.0.10
|
|
205
205
|
specification_version: 4
|
|
206
206
|
summary: Circuit breaker primitives for Rails apps, built on stoplight.
|
|
207
207
|
test_files: []
|