ruby_reactor 0.8.5 → 0.8.7

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.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/.release-please-manifest.json +1 -1
  3. data/.specify/feature.json +1 -1
  4. data/.specify/memory/constitution.md +17 -14
  5. data/CHANGELOG.md +82 -0
  6. data/CLAUDE.md +1 -1
  7. data/README.md +27 -8
  8. data/lib/ruby_reactor/adapters/active_job/map_element_rollback_worker.rb +20 -0
  9. data/lib/ruby_reactor/adapters/active_job/router.rb +32 -4
  10. data/lib/ruby_reactor/adapters/sidekiq/map_element_rollback_worker.rb +16 -0
  11. data/lib/ruby_reactor/adapters/sidekiq/router.rb +32 -4
  12. data/lib/ruby_reactor/context.rb +14 -1
  13. data/lib/ruby_reactor/dsl/definition_warnings.rb +30 -0
  14. data/lib/ruby_reactor/dsl/map_builder.rb +27 -7
  15. data/lib/ruby_reactor/dsl/step_builder.rb +8 -21
  16. data/lib/ruby_reactor/error/rescuable.rb +6 -1
  17. data/lib/ruby_reactor/error/rollback_handed_off.rb +27 -0
  18. data/lib/ruby_reactor/executor/compensation_manager.rb +39 -9
  19. data/lib/ruby_reactor/executor/result_handler.rb +88 -52
  20. data/lib/ruby_reactor/executor/retry_manager.rb +6 -5
  21. data/lib/ruby_reactor/executor/step_executor.rb +23 -1
  22. data/lib/ruby_reactor/executor.rb +186 -6
  23. data/lib/ruby_reactor/map/collector.rb +25 -93
  24. data/lib/ruby_reactor/map/dispatcher.rb +38 -7
  25. data/lib/ruby_reactor/map/element_executor.rb +14 -10
  26. data/lib/ruby_reactor/map/element_rollback.rb +158 -0
  27. data/lib/ruby_reactor/map/helpers.rb +11 -155
  28. data/lib/ruby_reactor/map/step_rollback.rb +136 -0
  29. data/lib/ruby_reactor/map/sweeper.rb +66 -8
  30. data/lib/ruby_reactor/map.rb +17 -0
  31. data/lib/ruby_reactor/max_retries_exhausted_failure.rb +4 -2
  32. data/lib/ruby_reactor/reactor.rb +113 -24
  33. data/lib/ruby_reactor/rspec/active_job_helpers.rb +13 -2
  34. data/lib/ruby_reactor/rspec/matchers.rb +55 -37
  35. data/lib/ruby_reactor/rspec/sidekiq_helpers.rb +7 -3
  36. data/lib/ruby_reactor/rspec/test_subject.rb +21 -21
  37. data/lib/ruby_reactor/rspec.rb +3 -6
  38. data/lib/ruby_reactor/step/compose_step.rb +13 -0
  39. data/lib/ruby_reactor/step/map_step.rb +117 -114
  40. data/lib/ruby_reactor/storage/adapter.rb +14 -0
  41. data/lib/ruby_reactor/storage/redis_adapter.rb +18 -2
  42. data/lib/ruby_reactor/storage/redis_map_rollback.rb +153 -0
  43. data/lib/ruby_reactor/storage/redis_reactor_scan.rb +1 -1
  44. data/lib/ruby_reactor/sweeper.rb +3 -1
  45. data/lib/ruby_reactor/version.rb +1 -1
  46. data/lib/ruby_reactor/web/api.rb +11 -1
  47. data/lib/ruby_reactor/web/public/assets/{index-CQbgHtd0.js → index-C6ejszCQ.js} +12 -12
  48. data/lib/ruby_reactor/web/public/assets/index-DM5darhy.css +1 -0
  49. data/lib/ruby_reactor/web/public/index.html +2 -2
  50. data/lib/ruby_reactor/worker.rb +4 -2
  51. data/specs/007-execution-flow-analysis/evidence/harness.rb +2 -0
  52. data/specs/007-execution-flow-analysis/evidence/probes/03_map.rb +4 -1
  53. data/specs/009-distributed-map-undo/checklists/requirements.md +53 -0
  54. data/specs/009-distributed-map-undo/contracts/api-surface.md +125 -0
  55. data/specs/009-distributed-map-undo/contracts/rollback-protocol.md +157 -0
  56. data/specs/009-distributed-map-undo/data-model.md +151 -0
  57. data/specs/009-distributed-map-undo/plan.md +323 -0
  58. data/specs/009-distributed-map-undo/pr-description.md +78 -0
  59. data/specs/009-distributed-map-undo/quickstart.md +154 -0
  60. data/specs/009-distributed-map-undo/research.md +585 -0
  61. data/specs/009-distributed-map-undo/spec.md +360 -0
  62. data/specs/009-distributed-map-undo/tasks.md +1060 -0
  63. data/specs/010-interrupt-in-composed-child/checklists/requirements.md +43 -0
  64. data/specs/010-interrupt-in-composed-child/contracts/api-surface.md +75 -0
  65. data/specs/010-interrupt-in-composed-child/data-model.md +40 -0
  66. data/specs/010-interrupt-in-composed-child/plan.md +149 -0
  67. data/specs/010-interrupt-in-composed-child/quickstart.md +64 -0
  68. data/specs/010-interrupt-in-composed-child/research.md +207 -0
  69. data/specs/010-interrupt-in-composed-child/spec.md +267 -0
  70. data/specs/010-interrupt-in-composed-child/tasks.md +315 -0
  71. data/specs/future_improvements.md +9 -33
  72. metadata +29 -3
  73. data/lib/ruby_reactor/web/public/assets/index-BQvIWPdx.css +0 -1
@@ -173,7 +173,7 @@ module RubyReactor
173
173
 
174
174
  def self.reactor_status(data)
175
175
  status = data[:status].to_s == "skipped" ? "halted" : data[:status].to_s
176
- return status if %w[failed paused completed running halted pending aborted].include?(status)
176
+ return status if %w[failed paused completed running rolling_back halted pending aborted].include?(status)
177
177
  return "cancelled" if data[:cancelled]
178
178
  return "running" if data[:current_step]
179
179
  return "completed" if execution_evidence?(data)
@@ -393,7 +393,17 @@ module RubyReactor
393
393
  ref_data.merge("context" => child)
394
394
  end
395
395
 
396
+ # A map that rolled back distributed also carries its progress, `{
397
+ # total, settled, outstanding, failed }` (009 R-15). The records outlive
398
+ # the run, so a client shows it only while the run is `rolling_back`.
396
399
  def self.hydrate_map_ref(ref_data, reactor_class_name)
400
+ map_id = ref_data[:map_id] || ref_data["map_id"]
401
+ hydrated = hydrate_map_element(ref_data, reactor_class_name)
402
+ rollback = map_id && RubyReactor.configuration.storage_adapter.map_rollback_summary(map_id, reactor_class_name)
403
+ rollback ? hydrated.merge("rollback" => rollback.transform_keys(&:to_s)) : hydrated
404
+ end
405
+
406
+ def self.hydrate_map_element(ref_data, reactor_class_name)
397
407
  storage = RubyReactor.configuration.storage_adapter
398
408
  map_id = ref_data[:map_id] || ref_data["map_id"]
399
409