diff --git a/src/Internal/Workflow/ChildWorkflowStub.php b/src/Internal/Workflow/ChildWorkflowStub.php
index 5c5f890e..614c54d1 100644
--- a/src/Internal/Workflow/ChildWorkflowStub.php
+++ b/src/Internal/Workflow/ChildWorkflowStub.php
@@ -62,6 +62,21 @@ public function getExecution(): PromiseInterface
return $this->execution->promise();
}
+ public function start(... $args): PromiseInterface
+ {
+ if ($this->request !== null) {
+ throw new \LogicException('Child workflow already has been executed');
+ }
+
+ $this->request = new ExecuteChildWorkflow(
+ $this->workflow,
+ EncodedValues::fromValues($args),
+ $this->getOptionsArray()
+ );
+
+ return $this->request($this->request);
+ }
+
/**
* {@inheritDoc}
*/
diff --git a/src/Workflow.php b/src/Workflow.php
index de4b8c5b..424d149a 100644
--- a/src/Workflow.php
+++ b/src/Workflow.php
@@ -25,6 +25,7 @@
use Temporal\Workflow\ChildWorkflowStubInterface;
use Temporal\Workflow\ContinueAsNewOptions;
use Temporal\Workflow\ExternalWorkflowStubInterface;
+use Temporal\Workflow\ParentClosePolicy;
use Temporal\Workflow\ScopedContextInterface;
use Temporal\Internal\Workflow\WorkflowContext;
use Temporal\Workflow\WorkflowExecution;
@@ -634,6 +635,7 @@ public static function executeChildWorkflow(
* This method is equivalent to {@see Workflow::executeChildWorkflow}, but
* it takes the workflow class as the first argument, and the further api
* is built on the basis of calls to the methods of the passed workflow.
+ * For starting abandon child workflow {@see Workflow::newUntypedChildWorkflowStub()}.
*
*
* // Any workflow interface example:
@@ -696,6 +698,23 @@ public static function newChildWorkflowStub(string $class, ChildWorkflowOptions
* }
*
*
+ * To start abandoned child workflow use `yield` and method `start()`:
+ *
+ *
+ * #[WorkflowMethod]
+ * public function handler()
+ * {
+ * // ExampleWorkflow proxy
+ * $workflow = Workflow::newUntypedChildWorkflowStub(
+ * 'WorkflowName',
+ * ChildWorkflowOptions::new()->withParentClosePolicy(ParentClosePolicy::POLICY_ABANDON)
+ * );
+ *
+ * // Start child workflow
+ * yield $workflow->start(42);
+ * }
+ *
+ *
* @param string $name
* @param ChildWorkflowOptions|null $options
* @return ChildWorkflowStubInterface
diff --git a/src/Workflow/ChildWorkflowStubInterface.php b/src/Workflow/ChildWorkflowStubInterface.php
index 0d14a8fb..3ee19820 100644
--- a/src/Workflow/ChildWorkflowStubInterface.php
+++ b/src/Workflow/ChildWorkflowStubInterface.php
@@ -40,6 +40,12 @@ public function getOptions(): ChildWorkflowOptions;
*/
public function execute(array $args = [], $returnType = null): PromiseInterface;
+ /**
+ * @param array $args
+ * @return CompletableResultInterface
+ */
+ public function start(... $args): PromiseInterface;
+
/**
* @param string $name
* @param array $args
diff --git a/tests/Fixtures/src/Workflow/AbandonedChildWithTimerWorkflow.php b/tests/Fixtures/src/Workflow/AbandonedChildWithTimerWorkflow.php
index 9339a172..e2251660 100644
--- a/tests/Fixtures/src/Workflow/AbandonedChildWithTimerWorkflow.php
+++ b/tests/Fixtures/src/Workflow/AbandonedChildWithTimerWorkflow.php
@@ -14,7 +14,7 @@
#[WorkflowInterface]
class AbandonedChildWithTimerWorkflow
{
- #[WorkflowMethod]
+ #[WorkflowMethod('abandoned_workflow')]
public function wait(int $timeoutInSeconds)
{
Workflow::timer($timeoutInSeconds);
diff --git a/tests/Fixtures/src/Workflow/ParentWithAbandonedChildWorkflow.php b/tests/Fixtures/src/Workflow/ParentWithAbandonedChildWorkflow.php
index 0a519de5..0f2bb18d 100644
--- a/tests/Fixtures/src/Workflow/ParentWithAbandonedChildWorkflow.php
+++ b/tests/Fixtures/src/Workflow/ParentWithAbandonedChildWorkflow.php
@@ -16,13 +16,13 @@ class ParentWithAbandonedChildWorkflow
#[WorkflowMethod]
public function start(int $childTimeoutInSeconds)
{
- $child = Workflow::newChildWorkflowStub(
- AbandonedChildWithTimerWorkflow::class,
+ $child = Workflow::newUntypedChildWorkflowStub(
+ 'abandoned_workflow',
ChildWorkflowOptions::new()
->withParentClosePolicy(ParentClosePolicy::POLICY_ABANDON)
);
- $child->wait($childTimeoutInSeconds);
+ yield $child->start($childTimeoutInSeconds);
return 'Welcome from parent';
}
diff --git a/tests/Functional/Client/AwaitTestCase.php b/tests/Functional/Client/AwaitTestCase.php
index da120bf4..0b4f1a5a 100644
--- a/tests/Functional/Client/AwaitTestCase.php
+++ b/tests/Functional/Client/AwaitTestCase.php
@@ -16,6 +16,7 @@
use Temporal\Exception\Failure\ActivityFailure;
use Temporal\Exception\Failure\ApplicationFailure;
use Temporal\Exception\Failure\CanceledFailure;
+use Temporal\Testing\WithoutTimeSkipping;
use Temporal\Tests\Workflow\AggregatedWorkflow;
use Temporal\Tests\Workflow\LoopWithSignalCoroutinesWorkflow;
use Temporal\Tests\Workflow\LoopWorkflow;
@@ -28,6 +29,8 @@
*/
class AwaitTestCase extends ClientTestCase
{
+ use WithoutTimeSkipping;
+
public function testSimpleAwait()
{
$client = $this->createClient();
diff --git a/tests/Functional/Client/ExternalWorkflowTestCase.php b/tests/Functional/Client/ExternalWorkflowTestCase.php
index f69f37b7..d6a17250 100644
--- a/tests/Functional/Client/ExternalWorkflowTestCase.php
+++ b/tests/Functional/Client/ExternalWorkflowTestCase.php
@@ -13,12 +13,15 @@
use Temporal\Exception\Client\WorkflowFailedException;
use Temporal\Exception\Failure\CanceledFailure;
+use Temporal\Testing\WithoutTimeSkipping;
use Temporal\Tests\Workflow\LoopKillerWorkflow;
use Temporal\Tests\Workflow\LoopSignallingWorkflow;
use Temporal\Tests\Workflow\LoopWorkflow;
class ExternalWorkflowTestCase extends ClientTestCase
{
+ use WithoutTimeSkipping;
+
public function testSignalWorkflowExecution()
{
$client = $this->createClient();