From 5d320c7617ec97c8f62c39eb4eab092ba19e2f48 Mon Sep 17 00:00:00 2001 From: Richard McDaniel Date: Mon, 23 Feb 2026 10:57:34 -0600 Subject: [PATCH] Fix timer replay --- src/Traits/AwaitWithTimeouts.php | 10 ++++++++- .../Feature/AwaitWithTimeoutWorkflowTest.php | 13 +++++++++++ .../TestAwaitWithTimeoutReplayWorkflow.php | 21 ++++++++++++++++++ tests/Unit/Traits/AwaitWithTimeoutsTest.php | 22 +++++++++++++++++++ tests/Unit/Traits/TimersTest.php | 2 +- 5 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 tests/Fixtures/TestAwaitWithTimeoutReplayWorkflow.php diff --git a/src/Traits/AwaitWithTimeouts.php b/src/Traits/AwaitWithTimeouts.php index bf9aaa33..81e513ec 100644 --- a/src/Traits/AwaitWithTimeouts.php +++ b/src/Traits/AwaitWithTimeouts.php @@ -10,6 +10,7 @@ use function React\Promise\resolve; use Workflow\Serializers\Serializer; use Workflow\Signal; +use Workflow\Timer; trait AwaitWithTimeouts { @@ -19,7 +20,14 @@ public static function awaitWithTimeout(int|string|CarbonInterval $seconds, $con if ($log) { ++self::$context->index; - return resolve(Serializer::unserialize($log->result)); + + $result = Serializer::unserialize($log->result); + + if ($log->class === Timer::class) { + return resolve(! $result); + } + + return resolve($result); } $result = $condition(); diff --git a/tests/Feature/AwaitWithTimeoutWorkflowTest.php b/tests/Feature/AwaitWithTimeoutWorkflowTest.php index b3aef8df..6793a960 100644 --- a/tests/Feature/AwaitWithTimeoutWorkflowTest.php +++ b/tests/Feature/AwaitWithTimeoutWorkflowTest.php @@ -4,6 +4,7 @@ namespace Tests\Feature; +use Tests\Fixtures\TestAwaitWithTimeoutReplayWorkflow; use Tests\Fixtures\TestAwaitWithTimeoutWorkflow; use Tests\TestCase; use Workflow\States\WorkflowCompletedStatus; @@ -40,4 +41,16 @@ public function testTimedout(): void $this->assertSame(WorkflowCompletedStatus::class, $workflow->status()); $this->assertSame('workflow_timed_out', $workflow->output()); } + + public function testTimedoutResultStaysFalseAfterReplay(): void + { + $workflow = WorkflowStub::make(TestAwaitWithTimeoutReplayWorkflow::class); + + $workflow->start(); + + while ($workflow->running()); + + $this->assertSame(WorkflowCompletedStatus::class, $workflow->status()); + $this->assertFalse($workflow->output()); + } } diff --git a/tests/Fixtures/TestAwaitWithTimeoutReplayWorkflow.php b/tests/Fixtures/TestAwaitWithTimeoutReplayWorkflow.php new file mode 100644 index 00000000..42572283 --- /dev/null +++ b/tests/Fixtures/TestAwaitWithTimeoutReplayWorkflow.php @@ -0,0 +1,21 @@ + false); + + yield activity(TestCountActivity::class, $result ? 1 : 0); + + return $result; + } +} diff --git a/tests/Unit/Traits/AwaitWithTimeoutsTest.php b/tests/Unit/Traits/AwaitWithTimeoutsTest.php index cd584e0a..5ba1f24a 100644 --- a/tests/Unit/Traits/AwaitWithTimeoutsTest.php +++ b/tests/Unit/Traits/AwaitWithTimeoutsTest.php @@ -11,6 +11,7 @@ use Workflow\Serializers\Serializer; use Workflow\Signal; use Workflow\States\WorkflowPendingStatus; +use Workflow\Timer; use Workflow\WorkflowStub; final class AwaitWithTimeoutsTest extends TestCase @@ -87,6 +88,27 @@ public function testLoadsStoredResult(): void $this->assertTrue(Serializer::unserialize($workflow->logs()->firstWhere('index', 0)->result)); } + public function testLoadsStoredTimerResultAsTimedOut(): void + { + $workflow = WorkflowStub::load(WorkflowStub::make(TestWorkflow::class)->id()); + $storedWorkflow = StoredWorkflow::findOrFail($workflow->id()); + $storedWorkflow->logs() + ->create([ + 'index' => 0, + 'now' => WorkflowStub::now(), + 'class' => Timer::class, + 'result' => Serializer::serialize(true), + ]); + + WorkflowStub::awaitWithTimeout('1 minute', static fn () => true) + ->then(static function ($value) use (&$result) { + $result = $value; + }); + + $this->assertSame(false, $result); + $this->assertSame(1, $workflow->logs()->count()); + } + public function testResolvesConflictingResult(): void { $workflow = WorkflowStub::load(WorkflowStub::make(TestWorkflow::class)->id()); diff --git a/tests/Unit/Traits/TimersTest.php b/tests/Unit/Traits/TimersTest.php index 1e0dfad7..0e5ead92 100644 --- a/tests/Unit/Traits/TimersTest.php +++ b/tests/Unit/Traits/TimersTest.php @@ -135,7 +135,7 @@ public function testLoadsStoredResult(): void $result = $value; }); - $this->assertSame(true, $result); + $this->assertSame(false, $result); $this->assertSame(1, $workflow->logs()->count()); $this->assertDatabaseHas('workflow_logs', [ 'stored_workflow_id' => $workflow->id(),