diff --git a/src/Internal/Transport/Request/GetChildWorkflowExecution.php b/src/Internal/Transport/Request/GetChildWorkflowExecution.php index 3be1580d..844640d6 100644 --- a/src/Internal/Transport/Request/GetChildWorkflowExecution.php +++ b/src/Internal/Transport/Request/GetChildWorkflowExecution.php @@ -12,16 +12,28 @@ namespace Temporal\Internal\Transport\Request; use Temporal\Worker\Transport\Command\Request; +use Temporal\Workflow\ParentClosePolicy; final class GetChildWorkflowExecution extends Request { public const NAME = 'GetChildWorkflowExecution'; + /** @see ParentClosePolicy */ + private int $parentClosePolicy; /** * @param ExecuteChildWorkflow $execution */ public function __construct(ExecuteChildWorkflow $execution) { + $this->parentClosePolicy = $execution->getOptions()['options']['ParentClosePolicy'] ?? ParentClosePolicy::POLICY_UNSPECIFIED; parent::__construct(self::NAME, ['id' => $execution->getID()]); } + + /** + * We don't wait for child workflow with parent close policy ABANDON + */ + public function shouldBeWaitedFor(): bool + { + return $this->parentClosePolicy !== ParentClosePolicy::POLICY_ABANDON; + } } diff --git a/src/Internal/Workflow/Process/Scope.php b/src/Internal/Workflow/Process/Scope.php index 6d9e9b0a..7cdaf72f 100644 --- a/src/Internal/Workflow/Process/Scope.php +++ b/src/Internal/Workflow/Process/Scope.php @@ -386,7 +386,9 @@ protected function onRequest(RequestInterface $request, PromiseInterface $promis $cancelID = $this->cancelID; // do not close the scope until all promises are complete - $this->awaitLock++; + if ($request->shouldBeWaitedFor()) { + $this->awaitLock++; + } // do not cancel already complete promises $cleanup = function () use ($cancelID): void { diff --git a/src/Worker/Transport/Command/Request.php b/src/Worker/Transport/Command/Request.php index 06fbc4c4..169f13dd 100644 --- a/src/Worker/Transport/Command/Request.php +++ b/src/Worker/Transport/Command/Request.php @@ -82,4 +82,9 @@ public function getFailure(): ?\Throwable { return $this->failure; } + + public function shouldBeWaitedFor(): bool + { + return true; + } } diff --git a/src/Worker/Transport/Command/RequestInterface.php b/src/Worker/Transport/Command/RequestInterface.php index fda59197..bcd1be4b 100644 --- a/src/Worker/Transport/Command/RequestInterface.php +++ b/src/Worker/Transport/Command/RequestInterface.php @@ -36,4 +36,6 @@ public function getPayloads(): ValuesInterface; * @return \Throwable|null */ public function getFailure(): ?\Throwable; + + public function shouldBeWaitedFor(): bool; } diff --git a/tests/Fixtures/src/Workflow/AbandonedChildWithTimerWorkflow.php b/tests/Fixtures/src/Workflow/AbandonedChildWithTimerWorkflow.php new file mode 100644 index 00000000..9339a172 --- /dev/null +++ b/tests/Fixtures/src/Workflow/AbandonedChildWithTimerWorkflow.php @@ -0,0 +1,22 @@ +withParentClosePolicy(ParentClosePolicy::POLICY_ABANDON) + ); + + $child->wait($childTimeoutInSeconds); + + return 'Welcome from parent'; + } +} diff --git a/tests/Functional/Client/AbandonedChildWorkflowTestCase.php b/tests/Functional/Client/AbandonedChildWorkflowTestCase.php new file mode 100644 index 00000000..eb0033d1 --- /dev/null +++ b/tests/Functional/Client/AbandonedChildWorkflowTestCase.php @@ -0,0 +1,25 @@ +testingService->getCurrentTime(); + /** @var ParentWithAbandonedChildWorkflow $parentWorkflow */ + $parentWorkflow = $this->workflowClient->newWorkflowStub(ParentWithAbandonedChildWorkflow::class); + $parentWorkflow->start(10); + $timeAfterStart = $this->testingService->getCurrentTime(); + static::assertTrue($timeAfterStart->diffInSeconds($timeBeforeStart) < 2); + } +} + diff --git a/tests/worker.php b/tests/worker.php index 45103322..673c06fb 100644 --- a/tests/worker.php +++ b/tests/worker.php @@ -2,12 +2,7 @@ declare(strict_types=1); -use Temporal\DataConverter\DataConverter; use Temporal\WorkerFactory; -use Temporal\Worker\Transport\RoadRunner; -use Temporal\Worker\Transport\Goridge; -use Temporal\Tests; -use Spiral\Goridge\Relay; require __DIR__ . '/../vendor/autoload.php';