state_machines 0.100.2 → 0.100.4
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/lib/state_machines/transition.rb +60 -26
- data/lib/state_machines/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7b5d883e6f3259de8981a9855e50d6f2d859bbd7e9e10a4cc5b4d91ae3fec65f
|
4
|
+
data.tar.gz: 9185125133d36eeed7ae95875a825e0e9a2e4d73b7de286c65be589965d2613d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4786a92acf6011cc49c6e9f8daa0505d7bfcd26da0d244e351830aed0972ac12656ab39df4f9cf7b35fa4892c7afa02830b7ec0b33876a8624076e60fb273f21
|
7
|
+
data.tar.gz: e87573373f971cea02ebba3dcca45124f49d8ca6354c34756e55fd101deab5649ee349e62b05a3abb7d0fdde9ead78075984a089f7f3070fb4b4768c7af8fcc8
|
@@ -44,6 +44,7 @@ module StateMachines
|
|
44
44
|
@paused_fiber = nil
|
45
45
|
@resuming = false
|
46
46
|
@continuation_block = nil
|
47
|
+
@fiber_thread_storage = nil
|
47
48
|
|
48
49
|
@event = machine.events.fetch(event)
|
49
50
|
@from_state = machine.states.fetch(from_name)
|
@@ -201,7 +202,8 @@ module StateMachines
|
|
201
202
|
# this is an idempotent call on an already-paused transition. Just return true.
|
202
203
|
return true if @paused_fiber&.alive? && !options[:after]
|
203
204
|
|
204
|
-
#
|
205
|
+
# Always use fibers for compatibility with existing pause/resume functionality
|
206
|
+
# The fiber argument can still be used to explicitly control fiber usage
|
205
207
|
pausable_options = options.key?(:fiber) ? { fiber: options[:fiber] } : {}
|
206
208
|
|
207
209
|
# Check if we're resuming from a pause
|
@@ -288,6 +290,7 @@ module StateMachines
|
|
288
290
|
@paused_fiber = nil
|
289
291
|
@resuming = false
|
290
292
|
@continuation_block = nil
|
293
|
+
@fiber_thread_storage = nil
|
291
294
|
end
|
292
295
|
|
293
296
|
# Determines equality of transitions by testing whether the object, states,
|
@@ -380,27 +383,43 @@ module StateMachines
|
|
380
383
|
# Handle different result types
|
381
384
|
case result
|
382
385
|
when Array
|
383
|
-
# Exception occurred inside the fiber
|
384
386
|
if result[0] == :error
|
385
|
-
#
|
387
|
+
# Exception occurred inside the fiber
|
386
388
|
@paused_fiber = nil
|
387
389
|
raise result[1]
|
388
|
-
end
|
389
|
-
else
|
390
|
-
# Normal flow
|
391
|
-
# Check if fiber is still alive after resume
|
392
|
-
if @paused_fiber.alive?
|
393
|
-
# Still paused, keep the fiber
|
394
|
-
true
|
395
390
|
else
|
396
|
-
#
|
397
|
-
@
|
398
|
-
|
391
|
+
# Normal completion with thread storage export
|
392
|
+
@fiber_thread_storage = result[1] if result.length == 2 && result[1].is_a?(Hash)
|
393
|
+
result_value = result[0]
|
399
394
|
end
|
395
|
+
else
|
396
|
+
# Direct result value (paused or simple completion)
|
397
|
+
result_value = result
|
398
|
+
end
|
399
|
+
|
400
|
+
# Check if fiber is still alive after resume
|
401
|
+
if @paused_fiber.alive?
|
402
|
+
# Still paused, keep the fiber
|
403
|
+
true
|
404
|
+
else
|
405
|
+
# Fiber completed
|
406
|
+
@paused_fiber = nil
|
407
|
+
result_value == :halted
|
400
408
|
end
|
401
409
|
else
|
410
|
+
# Capture current fiber's Thread.current storage to preserve object identity
|
411
|
+
# This is needed for compatibility but has limitations with dynamic assignments
|
412
|
+
parent_fiber_locals = Thread.current.keys.each_with_object({}) do |key, storage|
|
413
|
+
storage[key] = Thread.current[key]
|
414
|
+
end
|
415
|
+
|
402
416
|
# Create a new fiber to run the block
|
403
417
|
fiber = Fiber.new do
|
418
|
+
# Restore parent's Thread.current storage with exact same object references
|
419
|
+
parent_fiber_locals.each do |key, value|
|
420
|
+
Thread.current[key] = value
|
421
|
+
end
|
422
|
+
|
404
423
|
# Mark that we're inside a pausable fiber
|
405
424
|
Fiber.current.extend(StateMachines::PausableFiber)
|
406
425
|
Fiber.current.state_machine_fiber_pausable = true
|
@@ -409,7 +428,13 @@ module StateMachines
|
|
409
428
|
yield
|
410
429
|
true
|
411
430
|
end
|
412
|
-
|
431
|
+
|
432
|
+
# Export the final thread storage state along with the result
|
433
|
+
thread_storage = Thread.current.keys.each_with_object({}) do |key, storage|
|
434
|
+
storage[key] = Thread.current[key]
|
435
|
+
end
|
436
|
+
|
437
|
+
[halted ? :halted : :completed, thread_storage]
|
413
438
|
rescue StandardError => e
|
414
439
|
# Store the exception for re-raising
|
415
440
|
[:error, e]
|
@@ -425,23 +450,28 @@ module StateMachines
|
|
425
450
|
# Handle different result types
|
426
451
|
case result
|
427
452
|
when Array
|
428
|
-
# Exception occurred
|
429
453
|
if result[0] == :error
|
430
|
-
#
|
454
|
+
# Exception occurred
|
431
455
|
@paused_fiber = nil
|
432
456
|
raise result[1]
|
433
|
-
end
|
434
|
-
else
|
435
|
-
# Normal flow
|
436
|
-
# Save if paused
|
437
|
-
if fiber.alive?
|
438
|
-
@paused_fiber = fiber
|
439
|
-
# Return true to indicate paused (treated as halted for flow control)
|
440
|
-
true
|
441
457
|
else
|
442
|
-
#
|
443
|
-
result ==
|
458
|
+
# Normal completion - check if we have thread storage
|
459
|
+
@fiber_thread_storage = result[1] if result.length == 2 && result[1].is_a?(Hash)
|
460
|
+
result_value = result[0]
|
444
461
|
end
|
462
|
+
else
|
463
|
+
# Direct result value (shouldn't happen with our new code)
|
464
|
+
result_value = result
|
465
|
+
end
|
466
|
+
|
467
|
+
# Save if paused
|
468
|
+
if fiber.alive?
|
469
|
+
@paused_fiber = fiber
|
470
|
+
# Return true to indicate paused (treated as halted for flow control)
|
471
|
+
true
|
472
|
+
else
|
473
|
+
# Fiber completed, return whether it was halted
|
474
|
+
result_value == :halted
|
445
475
|
end
|
446
476
|
end
|
447
477
|
end
|
@@ -539,6 +569,10 @@ module StateMachines
|
|
539
569
|
def after
|
540
570
|
return if @after_run
|
541
571
|
|
572
|
+
# Restore the fiber's thread storage to ensure consistency
|
573
|
+
# This preserves Thread.current state from before/around callbacks to after callbacks
|
574
|
+
@fiber_thread_storage.each { |key, value| Thread.current[key] = value } if @fiber_thread_storage
|
575
|
+
|
542
576
|
catch(:halt) do
|
543
577
|
type = @success ? :after : :failure
|
544
578
|
machine.callbacks[type].each { |callback| callback.call(object, context, self) }
|