diff --git a/src/Client/WorkflowClient.php b/src/Client/WorkflowClient.php index cd6c7c11..885f7d2a 100644 --- a/src/Client/WorkflowClient.php +++ b/src/Client/WorkflowClient.php @@ -262,6 +262,7 @@ public function updateWithStart( $startArgs, ); + // todo: set execution if UpdateWorkflow was failed but WF was started $workflowStub->setExecution($handle->getExecution()); return $handle; diff --git a/src/Internal/Client/ResponseToResultMapper.php b/src/Internal/Client/ResponseToResultMapper.php new file mode 100644 index 00000000..db8f3033 --- /dev/null +++ b/src/Internal/Client/ResponseToResultMapper.php @@ -0,0 +1,80 @@ +getOutcome(); + $updateRef = $result->getUpdateRef(); + \assert($updateRef !== null); + $updateRefDto = new UpdateRef( + new WorkflowExecution( + (string)$updateRef->getWorkflowExecution()?->getWorkflowId(), + $updateRef->getWorkflowExecution()?->getRunId(), + ), + $updateRef->getUpdateId(), + ); + + if ($outcome === null) { + // Not completed + return new StartUpdateOutput($updateRefDto, false, null); + } + + $failure = $outcome->getFailure(); + $success = $outcome->getSuccess(); + + + if ($success !== null) { + return new StartUpdateOutput( + $updateRefDto, + true, + EncodedValues::fromPayloads($success, $this->converter), + ); + } + + if ($failure !== null) { + $execution = $updateRef->getWorkflowExecution(); + throw new WorkflowUpdateException( + null, + $execution === null + ? $workflowExecution + : new WorkflowExecution($execution->getWorkflowId(), $execution->getRunId()), + workflowType: $workflowType, + updateId: $updateRef->getUpdateId(), + updateName: $updateName, + previous: FailureConverter::mapFailureToException($failure, $this->converter), + ); + } + + throw new \RuntimeException( + \sprintf( + 'Received unexpected outcome from update request: %s', + $outcome->getValue(), + ), + ); + } +} diff --git a/src/Internal/Client/WorkflowStarter.php b/src/Internal/Client/WorkflowStarter.php index dc574375..f108feaf 100644 --- a/src/Internal/Client/WorkflowStarter.php +++ b/src/Internal/Client/WorkflowStarter.php @@ -19,6 +19,7 @@ use Temporal\Api\Update\V1\Request as UpdateRequestMessage; use Temporal\Api\Workflowservice\V1\ExecuteMultiOperationRequest; use Temporal\Api\Workflowservice\V1\ExecuteMultiOperationRequest\Operation; +use Temporal\Api\Workflowservice\V1\ExecuteMultiOperationResponse\Response; use Temporal\Api\Workflowservice\V1\SignalWithStartWorkflowExecutionRequest; use Temporal\Api\Workflowservice\V1\StartWorkflowExecutionRequest; use Temporal\Api\Workflowservice\V1\UpdateWorkflowExecutionRequest; @@ -187,7 +188,7 @@ function (UpdateWithStartInput $input): UpdateHandle { ]; try { - $this->serviceClient->ExecuteMultiOperation( + $response = $this->serviceClient->ExecuteMultiOperation( (new ExecuteMultiOperationRequest()) ->setNamespace($this->clientOptions->namespace) ->setOperations($ops), @@ -222,16 +223,37 @@ function (UpdateWithStartInput $input): UpdateHandle { ); } + // Extract result + /** @var \ArrayAccess $responses */ + $responses = $response->getResponses(); + + // Start Workflow: get execution + $startResponse = $responses[0]->getStartWorkflow(); + \assert($startResponse !== null); + $execution = new WorkflowExecution($input->workflowStartInput->workflowId, $startResponse->getRunId()); + + // Update Workflow: get handler + $updateResponse = $responses[1]->getUpdateWorkflow(); + \assert($updateResponse !== null); + + $updateResult = (new \Temporal\Internal\Client\ResponseToResultMapper($this->converter)) + ->mapUpdateWorkflowResponse( + $updateResponse, + updateName: $input->updateInput->updateName, + workflowType: $input->workflowStartInput->workflowType, + workflowExecution: $execution, + ); + return new UpdateHandle( client: $this->serviceClient, clientOptions: $this->clientOptions, converter: $this->converter, - execution: $input->updateInput->workflowExecution, + execution: $updateResult->getReference()->workflowExecution, workflowType: $input->updateInput->workflowType, updateName: $input->updateInput->updateName, resultType: $input->updateInput->resultType, - updateId: $input->updateInput->updateId, - result: null, + updateId: $updateResult->getReference()->updateId, + result: $updateResult->getResult(), ); }, /** @see WorkflowClientCallsInterceptor::updateWithStart() */ diff --git a/src/Internal/Client/WorkflowStub.php b/src/Internal/Client/WorkflowStub.php index 9d85c55e..31ad5c1d 100644 --- a/src/Internal/Client/WorkflowStub.php +++ b/src/Internal/Client/WorkflowStub.php @@ -338,52 +338,13 @@ static function ( throw new WorkflowServiceException(null, $input->workflowExecution, $input->workflowType, $e); } - $outcome = $result->getOutcome(); - $updateRef = $result->getUpdateRef(); - \assert($updateRef !== null); - $updateRefDto = new UpdateRef( - new WorkflowExecution( - (string) $updateRef->getWorkflowExecution()?->getWorkflowId(), - $updateRef->getWorkflowExecution()?->getRunId(), - ), - $updateRef->getUpdateId(), - ); - - if ($outcome === null) { - // Not completed - return new StartUpdateOutput($updateRefDto, false, null); - } - - $failure = $outcome->getFailure(); - $success = $outcome->getSuccess(); - - - if ($success !== null) { - return new StartUpdateOutput( - $updateRefDto, - true, - EncodedValues::fromPayloads($success, $converter), + return (new \Temporal\Internal\Client\ResponseToResultMapper($converter)) + ->mapUpdateWorkflowResponse( + $result, + $input->updateName, + $input->workflowType, + $input->workflowExecution, ); - } - - if ($failure !== null) { - $execution = $updateRef->getWorkflowExecution(); - throw new WorkflowUpdateException( - null, - $execution === null - ? $input->workflowExecution - : new WorkflowExecution($execution->getWorkflowId(), $execution->getRunId()), - workflowType: $input->workflowType, - updateId: $updateRef->getUpdateId(), - updateName: $input->updateName, - previous: FailureConverter::mapFailureToException($failure, $converter), - ); - } - - throw new \RuntimeException(\sprintf( - 'Received unexpected outcome from update request: %s', - $outcome->getValue(), - )); }, /** @see WorkflowClientCallsInterceptor::update() */ 'update', diff --git a/tests/Acceptance/Extra/Update/UpdateWithStartTest.php b/tests/Acceptance/Extra/Update/UpdateWithStartTest.php index 4e78a93e..cf95d858 100644 --- a/tests/Acceptance/Extra/Update/UpdateWithStartTest.php +++ b/tests/Acceptance/Extra/Update/UpdateWithStartTest.php @@ -52,9 +52,10 @@ public function failWithBadUpdateName( ); try { - $this->expectException(WorkflowUpdateException::class); $client->updateWithStart($stub, 'await1234', ['key']); $this->fail('Update must fail'); + } catch (WorkflowUpdateException $e) { + $this->assertStringContainsString('await1234', $e->getPrevious()->getMessage()); } finally { try { $stub->getResult(timeout: 1);