diff --git a/composer.json b/composer.json index 2b34410..33ea81e 100644 --- a/composer.json +++ b/composer.json @@ -31,8 +31,7 @@ "php": "^8.0.2", "laravel/framework": "^9.19", "spatie/laravel-model-states": "^2.1", - "react/promise": "^2.9", - "opis/closure": "^3.6" + "react/promise": "^2.9" }, "require-dev": { "orchestra/testbench": "^7.1", diff --git a/src/Activity.php b/src/Activity.php index 4bb32b9..aba950f 100644 --- a/src/Activity.php +++ b/src/Activity.php @@ -65,6 +65,10 @@ public function handle() throw new BadMethodCallException('Execute method not implemented.'); } + if ($this->storedWorkflow->logs()->whereIndex($this->index)->exists()) { + return; + } + try { return $this->{'execute'}(...$this->arguments); } catch (\Throwable $throwable) { diff --git a/src/Serializers/Y.php b/src/Serializers/Y.php index 4cfc6b0..44a99ff 100644 --- a/src/Serializers/Y.php +++ b/src/Serializers/Y.php @@ -4,9 +4,7 @@ namespace Workflow\Serializers; -use Opis\Closure\SerializableClosure; -use function Opis\Closure\serialize as s; -use function Opis\Closure\unserialize as u; +use Laravel\SerializableClosure\SerializableClosure; final class Y implements SerializerInterface { @@ -42,12 +40,16 @@ public static function decode(string $data): string public static function serialize($data): string { SerializableClosure::setSecretKey(config('app.key')); - return self::encode(s($data)); + return self::encode(serialize(new SerializableClosure(static fn () => $data))); } public static function unserialize(string $data) { SerializableClosure::setSecretKey(config('app.key')); - return u(self::decode($data)); + $unserialized = unserialize(self::decode($data)); + if ($unserialized instanceof SerializableClosure) { + $unserialized = ($unserialized->getClosure())(); + } + return $unserialized; } } diff --git a/tests/Fixtures/TestEnum.php b/tests/Fixtures/TestEnum.php new file mode 100644 index 0000000..39b67ee --- /dev/null +++ b/tests/Fixtures/TestEnum.php @@ -0,0 +1,12 @@ + $workflow->id(), 'index' => 0, 'class' => TestActivity::class, - 'result' => Y::serialize('activity'), ]); + $this->assertSame('activity', Y::unserialize($workflow->logs()->firstWhere('index', 0)->result)); } public function testLoadsStoredResult(): void diff --git a/tests/Unit/ActivityTest.php b/tests/Unit/ActivityTest.php index e89ac81..8ddd7ca 100644 --- a/tests/Unit/ActivityTest.php +++ b/tests/Unit/ActivityTest.php @@ -12,6 +12,7 @@ use Tests\Fixtures\TestWorkflow; use Tests\TestCase; use Workflow\Models\StoredWorkflow; +use Workflow\Serializers\Y; use Workflow\States\WorkflowFailedStatus; use Workflow\WorkflowStub; @@ -26,8 +27,9 @@ public function testActivity(): void $activity->timeout = 1; $activity->heartbeat(); - $activity->handle(); + $result = $activity->handle(); + $this->assertSame(['other'], $result); $this->assertSame([1, 2, 5, 10, 15, 30, 60, 120], $activity->backoff()); $this->assertSame($workflow->id(), $activity->workflowId()); $this->assertSame($activity->timeout, pcntl_alarm(0)); @@ -78,4 +80,27 @@ public function testFailedActivity(): void $this->assertSame(0, $workflow->logs()->count()); $this->assertSame(WorkflowFailedStatus::class, $workflow->status()); } + + public function testActivityAlreadyComplete(): void + { + $workflow = WorkflowStub::load(WorkflowStub::make(TestWorkflow::class)->id()); + StoredWorkflow::findOrFail($workflow->id())->logs()->create([ + 'index' => 0, + 'now' => now(), + 'class' => TestOtherActivity::class, + 'result' => Y::serialize('other'), + ]); + $activity = new TestOtherActivity(0, now()->toDateTimeString(), StoredWorkflow::findOrFail($workflow->id()), [ + 'other', + ]); + $activity->timeout = 1; + $activity->heartbeat(); + + $result = $activity->handle(); + + $this->assertNull($result); + $this->assertSame([1, 2, 5, 10, 15, 30, 60, 120], $activity->backoff()); + $this->assertSame($workflow->id(), $activity->workflowId()); + $this->assertSame($activity->timeout, pcntl_alarm(0)); + } } diff --git a/tests/Unit/Serializers/SerializeTest.php b/tests/Unit/Serializers/SerializeTest.php index 1a98743..c7d13bf 100644 --- a/tests/Unit/Serializers/SerializeTest.php +++ b/tests/Unit/Serializers/SerializeTest.php @@ -4,6 +4,7 @@ namespace Tests\Unit\Serializers; +use Tests\Fixtures\TestEnum; use Tests\TestCase; use Workflow\Serializers\Y; @@ -32,6 +33,8 @@ public function dataProvider(): array ], 'bool true' => [true], 'bool false' => [false], + 'enum' => [TestEnum::First], + 'enum[]' => [[TestEnum::First]], 'int(PHP_INT_MIN)' => [PHP_INT_MIN], 'int(PHP_INT_MAX)' => [PHP_INT_MAX], 'int(-1)' => [-1], diff --git a/tests/Unit/Traits/AwaitWithTimeoutsTest.php b/tests/Unit/Traits/AwaitWithTimeoutsTest.php index e4c5b95..c773045 100644 --- a/tests/Unit/Traits/AwaitWithTimeoutsTest.php +++ b/tests/Unit/Traits/AwaitWithTimeoutsTest.php @@ -55,8 +55,8 @@ public function testStoresResult(): void 'stored_workflow_id' => $workflow->id(), 'index' => 0, 'class' => Signal::class, - 'result' => Y::serialize(true), ]); + $this->assertTrue(Y::unserialize($workflow->logs()->firstWhere('index', 0)->result)); } public function testLoadsStoredResult(): void @@ -82,8 +82,8 @@ public function testLoadsStoredResult(): void 'stored_workflow_id' => $workflow->id(), 'index' => 0, 'class' => Signal::class, - 'result' => Y::serialize(true), ]); + $this->assertTrue(Y::unserialize($workflow->logs()->firstWhere('index', 0)->result)); } public function testResolvesConflictingResult(): void @@ -111,7 +111,7 @@ public function testResolvesConflictingResult(): void 'stored_workflow_id' => $workflow->id(), 'index' => 0, 'class' => Signal::class, - 'result' => Y::serialize(false), ]); + $this->assertFalse(Y::unserialize($workflow->logs()->firstWhere('index', 0)->result)); } } diff --git a/tests/Unit/Traits/AwaitsTest.php b/tests/Unit/Traits/AwaitsTest.php index a1da364..873944d 100644 --- a/tests/Unit/Traits/AwaitsTest.php +++ b/tests/Unit/Traits/AwaitsTest.php @@ -41,8 +41,8 @@ public function testStoresResult(): void 'stored_workflow_id' => $workflow->id(), 'index' => 0, 'class' => Signal::class, - 'result' => Y::serialize(true), ]); + $this->assertTrue(Y::unserialize($workflow->logs()->firstWhere('index', 0)->result)); } public function testLoadsStoredResult(): void @@ -68,8 +68,8 @@ public function testLoadsStoredResult(): void 'stored_workflow_id' => $workflow->id(), 'index' => 0, 'class' => Signal::class, - 'result' => Y::serialize(true), ]); + $this->assertTrue(Y::unserialize($workflow->logs()->firstWhere('index', 0)->result)); } public function testResolvesConflictingResult(): void @@ -97,7 +97,7 @@ public function testResolvesConflictingResult(): void 'stored_workflow_id' => $workflow->id(), 'index' => 0, 'class' => Signal::class, - 'result' => Y::serialize(false), ]); + $this->assertFalse(Y::unserialize($workflow->logs()->firstWhere('index', 0)->result)); } } diff --git a/tests/Unit/Traits/SideEffectsTest.php b/tests/Unit/Traits/SideEffectsTest.php index e1794ea..74d470c 100644 --- a/tests/Unit/Traits/SideEffectsTest.php +++ b/tests/Unit/Traits/SideEffectsTest.php @@ -27,8 +27,8 @@ public function testStoresResult(): void 'stored_workflow_id' => $workflow->id(), 'index' => 0, 'class' => TestWorkflow::class, - 'result' => Y::serialize('test'), ]); + $this->assertSame('test', Y::unserialize($workflow->logs()->firstWhere('index', 0)->result)); } public function testLoadsStoredResult(): void @@ -54,8 +54,8 @@ public function testLoadsStoredResult(): void 'stored_workflow_id' => $workflow->id(), 'index' => 0, 'class' => TestWorkflow::class, - 'result' => Y::serialize('test'), ]); + $this->assertSame('test', Y::unserialize($workflow->logs()->firstWhere('index', 0)->result)); } public function testResolvesConflictingResult(): void @@ -83,7 +83,7 @@ public function testResolvesConflictingResult(): void 'stored_workflow_id' => $workflow->id(), 'index' => 0, 'class' => TestWorkflow::class, - 'result' => Y::serialize('test'), ]); + $this->assertSame('test', Y::unserialize($workflow->logs()->firstWhere('index', 0)->result)); } } diff --git a/tests/Unit/Traits/TimersTest.php b/tests/Unit/Traits/TimersTest.php index 8c4571b..cd1b5f2 100644 --- a/tests/Unit/Traits/TimersTest.php +++ b/tests/Unit/Traits/TimersTest.php @@ -103,8 +103,8 @@ public function testStoresResult(): void 'stored_workflow_id' => $workflow->id(), 'index' => 0, 'class' => Signal::class, - 'result' => Y::serialize(true), ]); + $this->assertSame(true, Y::unserialize($workflow->logs()->firstWhere('index', 0)->result)); } public function testLoadsStoredResult(): void @@ -135,7 +135,7 @@ public function testLoadsStoredResult(): void 'stored_workflow_id' => $workflow->id(), 'index' => 0, 'class' => Signal::class, - 'result' => Y::serialize(true), ]); + $this->assertSame(true, Y::unserialize($workflow->logs()->firstWhere('index', 0)->result)); } } diff --git a/tests/Unit/WorkflowStubTest.php b/tests/Unit/WorkflowStubTest.php index 630a12a..8772504 100644 --- a/tests/Unit/WorkflowStubTest.php +++ b/tests/Unit/WorkflowStubTest.php @@ -91,8 +91,8 @@ public function testAwait(): void 'stored_workflow_id' => $workflow->id(), 'index' => 1, 'class' => Signal::class, - 'result' => Y::serialize(true), ]); + $this->assertTrue(Y::unserialize($workflow->logs()->firstWhere('index', 1)->result)); $workflow->fresh(); $context = WorkflowStub::getContext(); @@ -130,8 +130,8 @@ public function testAwaitWithTimeout(): void 'stored_workflow_id' => $workflow->id(), 'index' => 1, 'class' => Signal::class, - 'result' => Y::serialize(true), ]); + $this->assertTrue(Y::unserialize($workflow->logs()->firstWhere('index', 1)->result)); $workflow->fresh(); $context = WorkflowStub::getContext(); @@ -178,7 +178,7 @@ public function testAwaitWithTimeoutTimedout(): void 'stored_workflow_id' => $workflow->id(), 'index' => 1, 'class' => Signal::class, - 'result' => Y::serialize(true), ]); + $this->assertTrue(Y::unserialize($workflow->logs()->firstWhere('index', 1)->result)); } } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy