diff --git a/src/Workflow/WorkflowInfo.php b/src/Workflow/WorkflowInfo.php index 26b4398bf..4b61f98ba 100644 --- a/src/Workflow/WorkflowInfo.php +++ b/src/Workflow/WorkflowInfo.php @@ -103,6 +103,12 @@ final class WorkflowInfo #[Marshal(name: 'ContinuedExecutionRunID')] public ?string $continuedExecutionRunId = null; + #[Marshal(name: 'FirstRunID')] + public ?string $firstExecutionRunId = null; + + #[Marshal(name: 'OriginalRunID')] + public ?string $originalExecutionRunId = null; + #[Marshal(name: 'ParentWorkflowNamespace')] public ?string $parentNamespace = null; diff --git a/tests/Acceptance/Extra/Workflow/WorkflowInfoTest.php b/tests/Acceptance/Extra/Workflow/WorkflowInfoTest.php index 9060325e3..1f37fb579 100644 --- a/tests/Acceptance/Extra/Workflow/WorkflowInfoTest.php +++ b/tests/Acceptance/Extra/Workflow/WorkflowInfoTest.php @@ -17,23 +17,59 @@ class WorkflowInfoTest extends TestCase { #[Test] public static function rootWorkflowExecution( - #[Stub('Extra_Workflow_WorkflowInfo', args: [MainWorkflow::ARG_ROOT_EXECUTION])] + #[Stub('Extra_Workflow_WorkflowInfo', args: [[MainWorkflow::ARG_ROOT_EXECUTION]])] WorkflowStubInterface $stub, ): void { $result = $stub->getResult(type: 'array'); self::assertSame([ - 'ID' => $stub->getExecution()->getID(), - 'RunID' => $stub->getExecution()->getRunID(), - ], $result); + 'id' => $stub->getExecution()->getID(), + 'runID' => $stub->getExecution()->getRunID(), + ], $result['rootExecution']); + } + + #[Test] + public static function continueAsNewExecution( + #[Stub('Extra_Workflow_WorkflowInfo', args: [[ + MainWorkflow::ARG_CONTINUE_AS_NEW, + MainWorkflow::ARG_DUMP, + ]])] + WorkflowStubInterface $stub, + ): void { + $result = $stub->getResult(type: 'array'); + self::assertNotEmpty($result['continuedExecutionRunId']); + self::assertSame($result['firstExecutionRunId'], $result['continuedExecutionRunId']); + self::assertNotSame($result['firstExecutionRunId'], $result['originalExecutionRunId']); + } + + #[Test] + public static function continueAsNewExecutionChild( + #[Stub('Extra_Workflow_WorkflowInfo', args: [[ + MainWorkflow::ARG_CONTINUE_AS_NEW, + MainWorkflow::ARG_RUN_MAIN_AS_CHILD, + MainWorkflow::ARG_DUMP, + ]])] + WorkflowStubInterface $stub, + ): void { + $result = $stub->getResult(type: 'array'); + /** + * There is no information about continued execution in child workflows. + */ + self::assertEmpty($result['continuedExecutionRunId']); + self::assertIsString($result['continuedExecutionRunId']); + self::assertSame($result['firstExecutionRunId'], $result['originalExecutionRunId']); } #[Test] public static function retryOptions( - #[Stub('Extra_Workflow_WorkflowInfo', args: [MainWorkflow::ARG_RETRY_OPTIONS], retryOptions: new RetryOptions( - backoffCoefficient: 3.0, - maximumInterval: '2 minutes', - maximumAttempts: 10, - ))] + #[Stub( + 'Extra_Workflow_WorkflowInfo', + args: [[MainWorkflow::ARG_RETRY_OPTIONS]], + retryOptions: new RetryOptions( + backoffCoefficient: 3.0, + maximumInterval: '2 minutes', + maximumAttempts: 10, + ), + )] WorkflowStubInterface $stub, ): void { $result = $stub->getResult(type: 'array'); @@ -52,13 +88,20 @@ class MainWorkflow { public const ARG_RETRY_OPTIONS = 'retryPolicy'; public const ARG_ROOT_EXECUTION = 'rootExecution'; + public const ARG_CONTINUE_AS_NEW = 'continueAsNew'; + public const ARG_DUMP = 'dump'; + public const ARG_RUN_MAIN_AS_CHILD = 'runMainAsChild'; #[WorkflowMethod('Extra_Workflow_WorkflowInfo')] - public function run($arg) + public function run(array $actions) { - return yield match ($arg) { + $action = \array_shift($actions); + return yield match ($action) { self::ARG_ROOT_EXECUTION => Workflow::newChildWorkflowStub(ChildWorkflow::class)->run(), - self::ARG_RETRY_OPTIONS => Workflow::getCurrentContext()->getInfo()->retryOptions, + self::ARG_RETRY_OPTIONS => Workflow::getInfo()->retryOptions, + self::ARG_CONTINUE_AS_NEW => Workflow::continueAsNew('Extra_Workflow_WorkflowInfo', args: [$actions]), + self::ARG_RUN_MAIN_AS_CHILD => Workflow::newChildWorkflowStub(MainWorkflow::class)->run($actions), + self::ARG_DUMP => Helper::dumpWorkflow(), }; } } @@ -79,6 +122,23 @@ class ChildWorkflow2 #[WorkflowMethod('Extra_Workflow_WorkflowInfo_Child2')] public function run() { - return Workflow::getCurrentContext()->getInfo()->rootExecution; + return Helper::dumpWorkflow(); + } +} + +class Helper +{ + public static function dumpWorkflow(): array + { + $workflowInfo = Workflow::getInfo(); + return [ + 'rootExecution' => [ + 'id' => $workflowInfo->rootExecution?->getID(), + 'runID' => $workflowInfo->rootExecution?->getRunID(), + ], + 'firstExecutionRunId' => $workflowInfo->firstExecutionRunId, + 'continuedExecutionRunId' => $workflowInfo->continuedExecutionRunId, + 'originalExecutionRunId' => $workflowInfo->originalExecutionRunId, + ]; } } diff --git a/tests/Functional/NamedArgumentsTestCase.php b/tests/Functional/NamedArgumentsTestCase.php index 58ca91933..9584b8616 100644 --- a/tests/Functional/NamedArgumentsTestCase.php +++ b/tests/Functional/NamedArgumentsTestCase.php @@ -7,7 +7,6 @@ use Temporal\Client\GRPC\ServiceClient; use Temporal\Client\WorkflowClient; use Temporal\Client\WorkflowOptions; -use Temporal\Tests\Workflow\ContinuableWorkflow; use Temporal\Tests\Workflow\ContinuaWithTaskQueueWorkflow; use Temporal\Tests\Workflow\NamedArguments\ContinueAsNewNamedArgumentsWorkflow; use Temporal\Tests\Workflow\NamedArguments\ExecuteChildNamedArgumentsWorkflow; diff --git a/tests/Unit/DTO/WorkflowInfoTestCase.php b/tests/Unit/DTO/WorkflowInfoTestCase.php index 01941e666..1952ea833 100644 --- a/tests/Unit/DTO/WorkflowInfoTestCase.php +++ b/tests/Unit/DTO/WorkflowInfoTestCase.php @@ -41,6 +41,8 @@ public function testMarshalling(): void 'ShouldContinueAsNew' => false, 'CronSchedule' => null, 'ContinuedExecutionRunID' => null, + 'FirstRunID' => null, + 'OriginalRunID' => null, 'ParentWorkflowNamespace' => null, 'RootWorkflowExecution' => null, 'ParentWorkflowExecution' => null,