Skip to content

Commit

Permalink
Add WorkflowUpdateRPCTimeoutOrCanceledException; add a test case
Browse files Browse the repository at this point in the history
  • Loading branch information
roxblnfk committed Aug 19, 2024
1 parent c4b79a0 commit 48ff190
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 13 deletions.
20 changes: 13 additions & 7 deletions src/Client/Update/UpdateHandle.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Temporal\DataConverter\ValuesInterface;
use Temporal\Exception\Client\TimeoutException;
use Temporal\Exception\Client\WorkflowUpdateException;
use Temporal\Exception\Client\WorkflowUpdateRPCTimeoutOrCanceledException;
use Temporal\Exception\Failure\FailureConverter;
use Temporal\Workflow\WorkflowExecution;

Expand Down Expand Up @@ -70,7 +71,7 @@ public function hasResult(): bool
* @param int|float|null $timeout Timeout in seconds. Accuracy to milliseconds.
*
* @throws WorkflowUpdateException
* @throws TimeoutException
* @throws WorkflowUpdateRPCTimeoutOrCanceledException
*/
public function getResult(int|float|null $timeout = null): mixed
{
Expand All @@ -83,7 +84,7 @@ public function getResult(int|float|null $timeout = null): mixed
* @param int|float|null $timeout Timeout in seconds. Accuracy to milliseconds.
*
* @throws WorkflowUpdateException
* @throws TimeoutException
* @throws WorkflowUpdateRPCTimeoutOrCanceledException
*/
public function getEncodedValues(int|float|null $timeout = null): ValuesInterface
{
Expand All @@ -100,7 +101,7 @@ public function getEncodedValues(int|float|null $timeout = null): ValuesInterfac
* @param int|float|null $timeout Timeout in seconds. Accuracy to milliseconds.
*
* @psalm-assert !null $this->result
* @throws TimeoutException
* @throws WorkflowUpdateRPCTimeoutOrCanceledException
*/
private function fetchResult(int|float|null $timeout = null): void
{
Expand All @@ -116,10 +117,14 @@ private function fetchResult(int|float|null $timeout = null): void
(new \Temporal\Api\Update\V1\WaitPolicy())->setLifecycleStage(LifecycleStage::StageCompleted->value)
);

$response = $this->client->PollWorkflowExecutionUpdate(
$request,
$timeout === null ? null : $this->client->getContext()->withTimeout($timeout),
);
try {
$response = $this->client->PollWorkflowExecutionUpdate(
$request,
$timeout === null ? null : $this->client->getContext()->withTimeout($timeout),
);
} catch (TimeoutException $e) {
throw WorkflowUpdateRPCTimeoutOrCanceledException::fromTimeoutException($e);
}

// Workflow Uprate accepted
$result = $response->getOutcome();
Expand All @@ -135,6 +140,7 @@ private function fetchResult(int|float|null $timeout = null): void
$failure = $result->getFailure();
\assert($failure !== null);
$e = FailureConverter::mapFailureToException($failure, $this->converter);
tr($e);

$this->result = new WorkflowUpdateException(
$e->getMessage(),
Expand Down
6 changes: 5 additions & 1 deletion src/Client/WorkflowStubInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
use Temporal\Client\Update\UpdateOptions;
use Temporal\DataConverter\Type;
use Temporal\DataConverter\ValuesInterface;
use Temporal\Exception\Client\WorkflowUpdateException;
use Temporal\Exception\Client\WorkflowUpdateRPCTimeoutOrCanceledException;
use Temporal\Exception\IllegalStateException;
use Temporal\Workflow\CancellationScopeInterface;
use Temporal\Workflow\QueryMethod;
Expand Down Expand Up @@ -91,6 +93,8 @@ public function query(string $name, ...$args): ?ValuesInterface;
* @param non-empty-string $name Name of the update handler.
* @param mixed ...$args Arguments to pass to the update handler.
* @return ValuesInterface|null
* @throws WorkflowUpdateException
* @throws WorkflowUpdateRPCTimeoutOrCanceledException
*/
public function update(string $name, ...$args): ?ValuesInterface;

Expand All @@ -107,7 +111,7 @@ public function update(string $name, ...$args): ?ValuesInterface;
*
* @param non-empty-string|UpdateOptions $nameOrOptions Name of the update handler or update options.
* @param mixed ...$args Arguments to pass to the update handler.
* @return UpdateHandle
* @throws WorkflowUpdateRPCTimeoutOrCanceledException
*/
public function startUpdate(string|UpdateOptions $nameOrOptions, ...$args): UpdateHandle;

Expand Down
7 changes: 4 additions & 3 deletions src/Exception/Client/TimeoutException.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

use Temporal\Exception\TemporalException;

class TimeoutException extends TemporalException
{
}
/**
* RPC timeout or cancellation.
*/
class TimeoutException extends TemporalException {}
2 changes: 1 addition & 1 deletion src/Exception/Client/WorkflowUpdateException.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

use Temporal\Workflow\WorkflowExecution;

final class WorkflowUpdateException extends WorkflowException
class WorkflowUpdateException extends WorkflowException
{
public function __construct(
?string $message,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

/**
* This file is part of Temporal package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Temporal\Exception\Client;

/**
* Occurs when an update call times out or is cancelled.
*
* @note this is not related to any general concept of timing out or cancelling a running update,
* this is only related to the client call itself.
*/
class WorkflowUpdateRPCTimeoutOrCanceledException extends TimeoutException {
public static function fromTimeoutException(TimeoutException $exception): self
{
return new self(
$exception->getMessage(),
$exception->getCode(),
$exception->getPrevious(),
);
}
}
3 changes: 3 additions & 0 deletions src/Internal/Client/WorkflowStub.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
use Temporal\Exception\Client\WorkflowQueryRejectedException;
use Temporal\Exception\Client\WorkflowServiceException;
use Temporal\Exception\Client\WorkflowUpdateException;
use Temporal\Exception\Client\WorkflowUpdateRPCTimeoutOrCanceledException;
use Temporal\Exception\Failure\CanceledFailure;
use Temporal\Exception\Failure\FailureConverter;
use Temporal\Exception\Failure\TerminatedFailure;
Expand Down Expand Up @@ -332,6 +333,8 @@ static function (
}

throw WorkflowServiceException::withoutMessage($input->workflowExecution, $input->workflowType, $e);
} catch (TimeoutException $e) {
throw WorkflowUpdateRPCTimeoutOrCanceledException::fromTimeoutException($e);
} catch (\Throwable $e) {
throw new WorkflowServiceException(null, $input->workflowExecution, $input->workflowType, $e);
}
Expand Down
2 changes: 1 addition & 1 deletion tests/Acceptance/App/Attribute/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
final class Client
{
public function __construct(
public int|string|null $timeout = null,
public float|null $timeout = null,
public \Closure|array|string|null $pipelineProvider = null,
public array $payloadConverters = [],
) {
Expand Down
75 changes: 75 additions & 0 deletions tests/Acceptance/Extra/Update/TimeoutTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

declare(strict_types=1);

namespace Temporal\Tests\Acceptance\Extra\Update\TimeoutTest;

use PHPUnit\Framework\Attributes\Test;
use Temporal\Client\WorkflowClientInterface;
use Temporal\Client\WorkflowOptions;
use Temporal\Client\WorkflowStubInterface;
use Temporal\Exception\Client\WorkflowUpdateRPCTimeoutOrCanceledException;
use Temporal\Tests\Acceptance\App\Attribute\Client;
use Temporal\Tests\Acceptance\App\Attribute\Stub;
use Temporal\Tests\Acceptance\App\TestCase;
use Temporal\Workflow;
use Temporal\Workflow\WorkflowInterface;
use Temporal\Workflow\WorkflowMethod;

class TimeoutTest extends TestCase
{
#[Test]
public function getUpdateResultFromHandler(
#[Stub('Extra_Timeout_WorkflowUpdate')]
WorkflowStubInterface $stub,
): void {
/** @see TestWorkflow::sleep */
$handle = $stub->startUpdate('sleep', '1 second');

$this->expectException(WorkflowUpdateRPCTimeoutOrCanceledException::class);

$handle->getResult(0.2);
}

#[Test]
public function doUpdateWithTimeout(
#[Stub('Extra_Timeout_WorkflowUpdate')]
#[Client(timeout: 1.2)]
WorkflowStubInterface $stub,
): void {
$this->expectException(WorkflowUpdateRPCTimeoutOrCanceledException::class);

/** @see TestWorkflow::sleep */
$stub->update('sleep', '2 second');
}

#[Test]
public function withoutRunningWorker(WorkflowClientInterface $client): void
{
$client = $client->withTimeout(1.2);
$wf = $client->newUntypedWorkflowStub('Extra_Timeout_WorkflowUpdate', WorkflowOptions::new()
->withTaskQueue('not-existing-task-queue'));
$client->start($wf);

$this->expectException(WorkflowUpdateRPCTimeoutOrCanceledException::class);

/** @see TestWorkflow::sleep */
$wf->update('sleep', '2 second');
}
}

#[WorkflowInterface]
class TestWorkflow
{
#[WorkflowMethod(name: "Extra_Timeout_WorkflowUpdate")]
public function handle()
{
yield Workflow::await(static fn() => false);
}

#[Workflow\UpdateMethod(name: 'sleep')]
public function sleep(string $sleep): mixed
{
yield Workflow::timer(\DateInterval::createFromDateString($sleep));
}
}

0 comments on commit 48ff190

Please sign in to comment.