diff --git a/src/Client/WorkflowClient.php b/src/Client/WorkflowClient.php index 23985c099..68cf557b0 100644 --- a/src/Client/WorkflowClient.php +++ b/src/Client/WorkflowClient.php @@ -250,7 +250,7 @@ public function updateWithStart( ); $workflowStub->hasExecution() and throw new InvalidArgumentException(self::ERROR_WORKFLOW_START_DUPLICATION); - [$execution, $handle] = $this->getStarter()->updateWithStart( + $output = $this->getStarter()->updateWithStart( $workflowType, $workflowStub->getOptions() ?? WorkflowOptions::new(), $update, @@ -258,11 +258,11 @@ public function updateWithStart( $startArgs, ); - $workflowStub->setExecution($execution); + $workflowStub->setExecution($output->execution); - return $handle instanceof \Throwable - ? throw $handle - : $handle; + return $output->handle instanceof UpdateHandle + ? $output->handle + : throw $output->handle; } /** diff --git a/src/Interceptor/Trait/WorkflowClientCallsInterceptorTrait.php b/src/Interceptor/Trait/WorkflowClientCallsInterceptorTrait.php index 5c07fb26a..3800ab132 100644 --- a/src/Interceptor/Trait/WorkflowClientCallsInterceptorTrait.php +++ b/src/Interceptor/Trait/WorkflowClientCallsInterceptorTrait.php @@ -11,7 +11,6 @@ namespace Temporal\Interceptor\Trait; -use Temporal\Client\Update\UpdateHandle; use Temporal\Client\Workflow\WorkflowExecutionDescription; use Temporal\DataConverter\EncodedValues; use Temporal\Interceptor\WorkflowClient\CancelInput; @@ -25,6 +24,7 @@ use Temporal\Interceptor\WorkflowClient\TerminateInput; use Temporal\Interceptor\WorkflowClient\UpdateInput; use Temporal\Interceptor\WorkflowClient\UpdateWithStartInput; +use Temporal\Interceptor\WorkflowClient\UpdateWithStartOutput; use Temporal\Interceptor\WorkflowClientCallsInterceptor; use Temporal\Workflow\WorkflowExecution; @@ -80,7 +80,7 @@ public function signalWithStart(SignalWithStartInput $input, callable $next): Wo * * @see WorkflowClientCallsInterceptor::updateWithStart() */ - public function updateWithStart(UpdateWithStartInput $input, callable $next): UpdateHandle + public function updateWithStart(UpdateWithStartInput $input, callable $next): UpdateWithStartOutput { return $next($input); } diff --git a/src/Interceptor/WorkflowClient/UpdateWithStartOutput.php b/src/Interceptor/WorkflowClient/UpdateWithStartOutput.php new file mode 100644 index 000000000..83a81c306 --- /dev/null +++ b/src/Interceptor/WorkflowClient/UpdateWithStartOutput.php @@ -0,0 +1,23 @@ +converter); $updateArguments = EncodedValues::fromValues($updateArgs, $this->converter); return $this->interceptors->with( - function (UpdateWithStartInput $input): array { + function (UpdateWithStartInput $input): UpdateWithStartOutput { $startRequest = $this->configureExecutionRequest( new StartWorkflowExecutionRequest(), $input->workflowStartInput, @@ -234,20 +233,23 @@ function (UpdateWithStartInput $input): array { workflowExecution: $execution, ); } catch (\RuntimeException $e) { - return [$execution, $e]; + return new UpdateWithStartOutput($execution, $e); } - return [$execution, new UpdateHandle( - client: $this->serviceClient, - clientOptions: $this->clientOptions, - converter: $this->converter, - execution: $updateResult->getReference()->workflowExecution, - workflowType: $input->updateInput->workflowType, - updateName: $input->updateInput->updateName, - resultType: $input->updateInput->resultType, - updateId: $updateResult->getReference()->updateId, - result: $updateResult->getResult(), - )]; + return new UpdateWithStartOutput( + $execution, + new UpdateHandle( + client: $this->serviceClient, + clientOptions: $this->clientOptions, + converter: $this->converter, + execution: $updateResult->getReference()->workflowExecution, + workflowType: $input->updateInput->workflowType, + updateName: $input->updateInput->updateName, + resultType: $input->updateInput->resultType, + updateId: $updateResult->getReference()->updateId, + result: $updateResult->getResult(), + ), + ); }, /** @see WorkflowClientCallsInterceptor::updateWithStart() */ 'updateWithStart', diff --git a/tests/Fixtures/src/Interceptor/InterceptorCallsCounter.php b/tests/Fixtures/src/Interceptor/InterceptorCallsCounter.php index e51f2498b..78d4cd199 100644 --- a/tests/Fixtures/src/Interceptor/InterceptorCallsCounter.php +++ b/tests/Fixtures/src/Interceptor/InterceptorCallsCounter.php @@ -21,8 +21,11 @@ use Temporal\Interceptor\Trait\WorkflowOutboundRequestInterceptorTrait; use Temporal\Interceptor\WorkflowClient\SignalWithStartInput; use Temporal\Interceptor\WorkflowClient\StartInput; +use Temporal\Interceptor\WorkflowClient\UpdateWithStartInput; +use Temporal\Interceptor\WorkflowClient\UpdateWithStartOutput; use Temporal\Interceptor\WorkflowClientCallsInterceptor; use Temporal\Interceptor\WorkflowInbound\SignalInput; +use Temporal\Interceptor\WorkflowInbound\UpdateInput; use Temporal\Interceptor\WorkflowInbound\WorkflowInput; use Temporal\Interceptor\WorkflowInboundCallsInterceptor; use Temporal\Interceptor\WorkflowOutboundRequestInterceptor; @@ -92,4 +95,15 @@ public function signalWithStart(SignalWithStartInput $input, callable $next): Wo ), ); } + + public function updateWithStart(UpdateWithStartInput $input, callable $next): UpdateWithStartOutput + { + return $next( + $input->with( + workflowStartInput: $input->workflowStartInput->with( + header: $this->increment($input->workflowStartInput->header, __FUNCTION__), + ), + ), + ); + } } diff --git a/tests/Fixtures/src/Workflow/Interceptor/UpdateHeadersWorkflow.php b/tests/Fixtures/src/Workflow/Interceptor/UpdateHeadersWorkflow.php new file mode 100644 index 000000000..de454dcb0 --- /dev/null +++ b/tests/Fixtures/src/Workflow/Interceptor/UpdateHeadersWorkflow.php @@ -0,0 +1,44 @@ + $this->updated); + + $this->headers = \iterator_to_array(Workflow::getCurrentContext()->getHeader()); + + return $this->headers; + } + + #[Workflow\UpdateMethod] + public function update(): void + { + $this->updated = true; + } + + #[Workflow\QueryMethod] + public function headers(): mixed + { + return $this->headers; + } +} diff --git a/tests/Functional/Interceptor/InterceptorsTestCase.php b/tests/Functional/Interceptor/InterceptorsTestCase.php index b41db0a9c..ced3d0bbf 100644 --- a/tests/Functional/Interceptor/InterceptorsTestCase.php +++ b/tests/Functional/Interceptor/InterceptorsTestCase.php @@ -12,11 +12,14 @@ namespace Temporal\Tests\Functional\Interceptor; use Carbon\CarbonInterval; +use Temporal\Client\Update\LifecycleStage; +use Temporal\Client\Update\UpdateOptions; use Temporal\Client\WorkflowOptions; use Temporal\Testing\WithoutTimeSkipping; use Temporal\Tests\Workflow\Interceptor\HeadersWorkflow; use Temporal\Tests\Workflow\Interceptor\QueryHeadersWorkflow; use Temporal\Tests\Workflow\Interceptor\SignalHeadersWorkflow; +use Temporal\Tests\Workflow\Interceptor\UpdateHeadersWorkflow; /** * @group client @@ -111,6 +114,30 @@ public function testSignalWithStartMethod(): void ], (array)$run->getResult()); } + public function testUpdateWithStartMethod(): void + { + $client = $this->createClient(); + $workflow = $client->newWorkflowStub( + UpdateHeadersWorkflow::class, + WorkflowOptions::new() + ->withWorkflowExecutionTimeout(CarbonInterval::seconds(5)), + ); + + $run = $client->updateWithStart($workflow, 'update'); + + // Workflow header + $this->assertEquals([ + /** @see \Temporal\Tests\Interceptor\InterceptorCallsCounter::updateWithStart() */ + 'updateWithStart' => '1', + /** + * Inherited from handler run + * + * @see \Temporal\Tests\Interceptor\InterceptorCallsCounter::execute() + */ + 'execute' => '1', + ], (array) $workflow->headers()); + } + // todo: rewrite tests because there is no header in query call // todo: add test about dynamic query // public function testQueryMethod(): void