Skip to content

Commit

Permalink
Merge pull request #417: Expose WorkflowIdConflictPolicy
Browse files Browse the repository at this point in the history
  • Loading branch information
roxblnfk authored Apr 16, 2024
2 parents 0179c48 + cd9964b commit 8cdcc18
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 4 deletions.
3 changes: 3 additions & 0 deletions src/Client/Workflow/WorkflowExecutionDescription.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
*/
final class WorkflowExecutionDescription
{
/**
* @internal
*/
public function __construct(
public readonly WorkflowExecutionInfo $info,
) {
Expand Down
31 changes: 27 additions & 4 deletions src/Client/WorkflowOptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use Temporal\Common\MethodRetry;
use Temporal\Common\RetryOptions;
use Temporal\Common\Uuid;
use Temporal\Common\WorkflowIdConflictPolicy;
use Temporal\DataConverter\DataConverterInterface;
use Temporal\Internal\Marshaller\Meta\Marshal;
use Temporal\Internal\Marshaller\Type\ArrayType;
Expand Down Expand Up @@ -98,12 +99,19 @@ final class WorkflowOptions extends Options
public \DateInterval $workflowTaskTimeout;

/**
* Whether server allow reuse of workflow ID, can be useful for deduplication logic.
* If set to {@see IdReusePolicy::POLICY_REJECT_DUPLICATE}.
* Whether server allow reuse of workflow ID.
*
* Can be useful for deduplication logic if set to {@see IdReusePolicy::POLICY_REJECT_DUPLICATE}.
*/
#[Marshal(name: 'WorkflowIDReusePolicy')]
public int $workflowIdReusePolicy = IdReusePolicy::POLICY_ALLOW_DUPLICATE_FAILED_ONLY;

/**
* Defines how to resolve an ID conflict with a *running* workflow.
*/
#[Marshal(name: 'WorkflowIdConflictPolicy')]
public WorkflowIdConflictPolicy $workflowIdConflictPolicy = WorkflowIdConflictPolicy::Unspecified;

/**
* Optional retry policy for workflow. If a retry policy is specified, in
* case of workflow failure server will start new workflow execution if
Expand Down Expand Up @@ -319,8 +327,8 @@ public function withWorkflowStartDelay($delay): self
}

/**
* Specifies server behavior if a completed workflow with the same id
* exists. Note that under no conditions Temporal allows two workflows
* Specifies server behavior if a *closed* workflow with the same id exists.
* Note that under no conditions Temporal allows two workflows
* with the same namespace and workflow id run simultaneously.
*
* - {@see IdReusePolicy::AllowDuplicateFailedOnly}: Is a default
Expand All @@ -347,6 +355,21 @@ public function withWorkflowIdReusePolicy(IdReusePolicy|int $policy): self
return $self;
}

/**
* Defines how to resolve an ID conflict with a *running* workflow.
*
* @psalm-suppress ImpureMethodCall
*
* @return $this
*/
#[Pure]
public function withWorkflowIdConflictPolicy(WorkflowIdConflictPolicy $policy): self
{
$self = clone $this;
$self->workflowIdConflictPolicy = $policy;
return $self;
}

/**
* RetryOptions that define how child workflow is retried in case of
* failure. Default is null which is no reties.
Expand Down
40 changes: 40 additions & 0 deletions src/Common/WorkflowIdConflictPolicy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?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\Common;

/**
* Defines what to do when trying to start a workflow with the same workflow id as a *running* workflow.
* Note that it is *never* valid to have two actively running instances of the same workflow id.
*
* @see IdReusePolicy for handling workflow id duplication with a *closed* workflow.
* @see \Temporal\Api\Enums\V1\WorkflowIdConflictPolicy
*/
enum WorkflowIdConflictPolicy: int
{
case Unspecified = 0;

/**
* Don't start a new workflow; instead return `WorkflowExecutionAlreadyStartedFailure`.
*/
case Fail = 1;

/**
* Don't start a new workflow; instead return a workflow handle for the running workflow.
*/
case UseExisting = 2;

/**
* Terminate the running workflow before starting a new one.
*/
case TerminateExisting = 3;

}
1 change: 1 addition & 0 deletions src/Internal/Client/WorkflowStarter.php
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ private function configureExecutionRequest(
->setCronSchedule($options->cronSchedule ?? '')
->setRetryPolicy($options->retryOptions ? $options->retryOptions->toWorkflowRetryPolicy() : null)
->setWorkflowIdReusePolicy($options->workflowIdReusePolicy)
->setWorkflowIdConflictPolicy($options->workflowIdConflictPolicy->value)
->setWorkflowRunTimeout(DateInterval::toDuration($options->workflowRunTimeout))
->setWorkflowExecutionTimeout(DateInterval::toDuration($options->workflowExecutionTimeout))
->setWorkflowTaskTimeout(DateInterval::toDuration($options->workflowTaskTimeout))
Expand Down
16 changes: 16 additions & 0 deletions tests/Unit/DTO/WorkflowOptionsTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use Temporal\Common\IdReusePolicy;
use Temporal\Common\RetryOptions;
use Temporal\Common\Uuid;
use Temporal\Common\WorkflowIdConflictPolicy;
use Temporal\DataConverter\DataConverter;

class WorkflowOptionsTestCase extends AbstractDTOMarshalling
Expand All @@ -38,6 +39,10 @@ public function testMarshalling(): void
'WorkflowStartDelay' => 0,
'WorkflowTaskTimeout' => 0,
'WorkflowIDReusePolicy' => 2,
'WorkflowIdConflictPolicy' => [
'name' => 'Unspecified',
'value' => 0,
],
'RetryPolicy' => null,
'CronSchedule' => null,
'Memo' => null,
Expand Down Expand Up @@ -125,6 +130,17 @@ public function testWorkflowIdReusePolicyChangesNotMutateStateUsingEnum(): void
$this->assertSame(IdReusePolicy::AllowDuplicateFailedOnly->value, $dto->workflowIdReusePolicy);
}

public function testWorkflowIdConflictPolicy(): void
{
$dto = new WorkflowOptions();

$this->assertNotSame($dto, $newDto = $dto->withWorkflowIdConflictPolicy(
WorkflowIdConflictPolicy::Fail
));
$this->assertSame(WorkflowIdConflictPolicy::Unspecified, $dto->workflowIdConflictPolicy);
$this->assertSame(WorkflowIdConflictPolicy::Fail, $newDto->workflowIdConflictPolicy);
}

public function testRetryOptionsChangesNotMutateState(): void
{
$dto = new WorkflowOptions();
Expand Down

0 comments on commit 8cdcc18

Please sign in to comment.