ruby_reactor 0.8.7 → 0.8.8
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/.release-please-manifest.json +1 -1
- data/.specify/feature.json +1 -1
- data/CHANGELOG.md +59 -2
- data/CLAUDE.md +1 -1
- data/README.md +38 -3
- data/lib/ruby_reactor/dsl/map_builder.rb +20 -1
- data/lib/ruby_reactor/error/recorded_failure.rb +18 -0
- data/lib/ruby_reactor/executor/compensation_manager.rb +21 -1
- data/lib/ruby_reactor/executor.rb +62 -10
- data/lib/ruby_reactor/interrupt_claims.rb +81 -0
- data/lib/ruby_reactor/map/step_rollback.rb +121 -0
- data/lib/ruby_reactor/reactor.rb +210 -95
- data/lib/ruby_reactor/rspec/matchers.rb +49 -0
- data/lib/ruby_reactor/rspec/test_subject.rb +17 -6
- data/lib/ruby_reactor/step/map_step.rb +12 -0
- data/lib/ruby_reactor/storage/adapter.rb +17 -0
- data/lib/ruby_reactor/storage/redis_adapter.rb +42 -0
- data/lib/ruby_reactor/version.rb +1 -1
- data/lib/ruby_reactor/web/api.rb +17 -0
- data/lib/ruby_reactor/web/public/assets/{index-C6ejszCQ.js → index-DxjQlW7Q.js} +8 -8
- data/lib/ruby_reactor/web/public/index.html +1 -1
- data/lib/ruby_reactor/worker.rb +73 -6
- data/specs/010-rollback-follow-ups/checklists/requirements.md +47 -0
- data/specs/010-rollback-follow-ups/contracts/api-surface.md +123 -0
- data/specs/010-rollback-follow-ups/contracts/resume-protocol.md +132 -0
- data/specs/010-rollback-follow-ups/data-model.md +139 -0
- data/specs/010-rollback-follow-ups/plan.md +273 -0
- data/specs/010-rollback-follow-ups/pr-description.md +110 -0
- data/specs/010-rollback-follow-ups/quickstart.md +157 -0
- data/specs/010-rollback-follow-ups/research.md +440 -0
- data/specs/010-rollback-follow-ups/spec.md +489 -0
- data/specs/010-rollback-follow-ups/tasks.md +1022 -0
- data/specs/future_improvements.md +17 -2
- metadata +14 -2
|
@@ -59,8 +59,8 @@ Found while auditing for 005 R-19:
|
|
|
59
59
|
| `Worker#handle_deserialization_failure` | before any executor | Writes a failed payload with no lock. |
|
|
60
60
|
| ~~Map collector, failure branch~~ | ~~`Map::Helpers#resume_parent_execution`~~ | Fixed by 009 R-03: the collector writes no context; it signals the owner run, whose Worker adopts the map's outcome. |
|
|
61
61
|
| `Reactor.cancel` | any process (app code, console) | `find` → mutate → `save_context`: a blind write racing a live worker. (`Reactor.undo` holds the run's `async:` lock since 009 R-12.) |
|
|
62
|
-
|
|
|
63
|
-
| Synchronous `Reactor.run` / `Executor#execute
|
|
62
|
+
| ~~`Reactor#continue` (interrupt resume)~~ | ~~web request / app code~~ | Fixed by 010 R-04/R-05: the payload is claimed in its own key; the run is written only after taking its lock and reloading it (or by the Worker it hands off to). |
|
|
63
|
+
| ~~Synchronous `Reactor.run` / `Executor#execute`~~ | ~~caller's process~~ | Fixed by 010 R-01: it holds the run's `async:` lock for its whole run and saves before releasing it. |
|
|
64
64
|
|
|
65
65
|
Writers that already belong to the owning execution:
|
|
66
66
|
- `Executor#save_context` and `#checkpoint!` on the worker path;
|
|
@@ -117,6 +117,10 @@ create-only `SET NX` equivalent. It covers `Reactor#save_context` at enqueue and
|
|
|
117
117
|
|
|
118
118
|
#### 2. Lock, then load
|
|
119
119
|
|
|
120
|
+
**Status (010):** done for `Worker#perform` (R-02), `Reactor#continue` (R-05) and `Reactor#undo`
|
|
121
|
+
(R-09); a synchronous `Reactor.run` holds the lock for its whole run (R-01). Versioned writes
|
|
122
|
+
(part 1) and the remaining writers above are still open.
|
|
123
|
+
|
|
120
124
|
- A worker takes the context lock **before** it reads the context. The restructure:
|
|
121
125
|
`Worker#perform` acquires `async:<root id>`, then retrieves and deserializes, then hands
|
|
122
126
|
the token and the loaded version to `Executor`. Today `resume_execution` acquires the lock
|
|
@@ -272,3 +276,14 @@ Raised while implementing specs/008-rollback-reliability. None blocks it.
|
|
|
272
276
|
saves `running` are separated only by the per-run context lock, which inline Sidekiq testing
|
|
273
277
|
skips. Accepted for now (008 review, 2026-09-27). Direction: claim the resume with an atomic
|
|
274
278
|
status compare-and-set.
|
|
279
|
+
## Interrupt inside a composed child
|
|
280
|
+
|
|
281
|
+
**Status:** unsupported on main, found while implementing 009 (US2-AS2). An `interrupt` in a
|
|
282
|
+
`compose`d child does not pause the root: `ComposeStep#handle_execution_result` calls `success?` on
|
|
283
|
+
the child's `InterruptResult`, and the compose step fails with `NoMethodError`. It fails the same
|
|
284
|
+
way with or without a fan-out map in the child.
|
|
285
|
+
|
|
286
|
+
Direction: propagate the child's `InterruptResult` as the compose step's result, so the root
|
|
287
|
+
pauses; let `Reactor.continue` and the `be_paused_at` matcher name the nested interrupt (a step
|
|
288
|
+
path such as `:fulfil, :approve`); and resume through `ComposeStep#run`, which already re-enters
|
|
289
|
+
an admitted child. Spec: `spec/map/map_compose_fan_out_spec.rb` keeps a `pending` example for it.
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ruby_reactor
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.8.
|
|
4
|
+
version: 0.8.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Artur
|
|
@@ -184,6 +184,7 @@ files:
|
|
|
184
184
|
- lib/ruby_reactor/error/execution_parked.rb
|
|
185
185
|
- lib/ruby_reactor/error/input_validation_error.rb
|
|
186
186
|
- lib/ruby_reactor/error/reactor_contention_park.rb
|
|
187
|
+
- lib/ruby_reactor/error/recorded_failure.rb
|
|
187
188
|
- lib/ruby_reactor/error/rescuable.rb
|
|
188
189
|
- lib/ruby_reactor/error/rollback_handed_off.rb
|
|
189
190
|
- lib/ruby_reactor/error/schema_version_error.rb
|
|
@@ -202,6 +203,7 @@ files:
|
|
|
202
203
|
- lib/ruby_reactor/executor/retry_manager.rb
|
|
203
204
|
- lib/ruby_reactor/executor/step_coordination.rb
|
|
204
205
|
- lib/ruby_reactor/executor/step_executor.rb
|
|
206
|
+
- lib/ruby_reactor/interrupt_claims.rb
|
|
205
207
|
- lib/ruby_reactor/interrupt_result.rb
|
|
206
208
|
- lib/ruby_reactor/lock.rb
|
|
207
209
|
- lib/ruby_reactor/map.rb
|
|
@@ -273,8 +275,8 @@ files:
|
|
|
273
275
|
- lib/ruby_reactor/web/application.rb
|
|
274
276
|
- lib/ruby_reactor/web/config.ru
|
|
275
277
|
- lib/ruby_reactor/web/coordination_serializer.rb
|
|
276
|
-
- lib/ruby_reactor/web/public/assets/index-C6ejszCQ.js
|
|
277
278
|
- lib/ruby_reactor/web/public/assets/index-DM5darhy.css
|
|
279
|
+
- lib/ruby_reactor/web/public/assets/index-DxjQlW7Q.js
|
|
278
280
|
- lib/ruby_reactor/web/public/index.html
|
|
279
281
|
- lib/ruby_reactor/web/public/vite.svg
|
|
280
282
|
- lib/ruby_reactor/worker.rb
|
|
@@ -338,6 +340,16 @@ files:
|
|
|
338
340
|
- specs/010-interrupt-in-composed-child/research.md
|
|
339
341
|
- specs/010-interrupt-in-composed-child/spec.md
|
|
340
342
|
- specs/010-interrupt-in-composed-child/tasks.md
|
|
343
|
+
- specs/010-rollback-follow-ups/checklists/requirements.md
|
|
344
|
+
- specs/010-rollback-follow-ups/contracts/api-surface.md
|
|
345
|
+
- specs/010-rollback-follow-ups/contracts/resume-protocol.md
|
|
346
|
+
- specs/010-rollback-follow-ups/data-model.md
|
|
347
|
+
- specs/010-rollback-follow-ups/plan.md
|
|
348
|
+
- specs/010-rollback-follow-ups/pr-description.md
|
|
349
|
+
- specs/010-rollback-follow-ups/quickstart.md
|
|
350
|
+
- specs/010-rollback-follow-ups/research.md
|
|
351
|
+
- specs/010-rollback-follow-ups/spec.md
|
|
352
|
+
- specs/010-rollback-follow-ups/tasks.md
|
|
341
353
|
- specs/future_improvements.md
|
|
342
354
|
- specs/scoped_rspec_matchers.md
|
|
343
355
|
- specs/specs-inputs-by-method-md-piped-wigderson.md
|