Skip to content

Commit bdf0c97

Browse files
committed
Merge branch 'master' into destroyable
# Conflicts: # src/Internal/Workflow/Process/Scope.php
2 parents 420e61d + 8dcc518 commit bdf0c97

File tree

13 files changed

+221
-78
lines changed

13 files changed

+221
-78
lines changed

psalm-baseline.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,6 +1176,14 @@
11761176
<PropertyNotSetInConstructor>
11771177
<code><![CDATA[$coroutine]]></code>
11781178
</PropertyNotSetInConstructor>
1179+
<RedundantCondition>
1180+
<code><![CDATA[$this->context?->destroy()]]></code>
1181+
<code><![CDATA[$this->scopeContext?->destroy()]]></code>
1182+
</RedundantCondition>
1183+
<TypeDoesNotContainNull>
1184+
<code><![CDATA[$this->context]]></code>
1185+
<code><![CDATA[$this->scopeContext]]></code>
1186+
</TypeDoesNotContainNull>
11791187
<UndefinedInterfaceMethod>
11801188
<code><![CDATA[catch]]></code>
11811189
<code><![CDATA[finally]]></code>

src/Common/RetryOptions.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ class RetryOptions extends Options
6868
* is 1.0 then it is used for all retries.
6969
*/
7070
#[Marshal(name: 'initial_interval', type: DurationJsonType::class, nullable: true)]
71+
#[Marshal(name: 'InitialInterval', type: DurationJsonType::class, nullable: true)]
7172
public ?\DateInterval $initialInterval = self::DEFAULT_INITIAL_INTERVAL;
7273

7374
/**
@@ -77,6 +78,7 @@ class RetryOptions extends Options
7778
* Note: Must be greater than 1.0
7879
*/
7980
#[Marshal(name: 'backoff_coefficient')]
81+
#[Marshal(name: 'BackoffCoefficient')]
8082
public float $backoffCoefficient = self::DEFAULT_BACKOFF_COEFFICIENT;
8183

8284
/**
@@ -86,6 +88,7 @@ class RetryOptions extends Options
8688
* Default is 100x of {@see $initialInterval}.
8789
*/
8890
#[Marshal(name: 'maximum_interval', type: DurationJsonType::class, nullable: true)]
91+
#[Marshal(name: 'MaximumInterval', type: DurationJsonType::class, nullable: true)]
8992
public ?\DateInterval $maximumInterval = self::DEFAULT_MAXIMUM_INTERVAL;
9093

9194
/**
@@ -96,6 +99,7 @@ class RetryOptions extends Options
9699
* @var int<0, max>
97100
*/
98101
#[Marshal(name: 'maximum_attempts')]
102+
#[Marshal(name: 'MaximumAttempts')]
99103
public int $maximumAttempts = self::DEFAULT_MAXIMUM_ATTEMPTS;
100104

101105
/**
@@ -105,6 +109,7 @@ class RetryOptions extends Options
105109
* @var ExceptionsList
106110
*/
107111
#[Marshal(name: 'non_retryable_error_types')]
112+
#[Marshal(name: 'NonRetryableErrorTypes')]
108113
public array $nonRetryableExceptions = self::DEFAULT_NON_RETRYABLE_EXCEPTIONS;
109114

110115
public function mergeWith(?MethodRetry $retry = null): self

src/Internal/Marshaller/MarshallingRule.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@
1313

1414
use Temporal\Internal\Marshaller\Type\TypeInterface;
1515

16-
/**
17-
* @internal
18-
*/
1916
class MarshallingRule
2017
{
2118
/**

src/Internal/Marshaller/Type/ArrayType.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ public static function makeRule(\ReflectionProperty $property): ?MarshallingRule
6363
*/
6464
public function parse($value, $current): array
6565
{
66+
if ($value === null) {
67+
return [];
68+
}
69+
6670
if (!\is_array($value)) {
6771
throw new \InvalidArgumentException(\sprintf(self::ERROR_INVALID_TYPE, \get_debug_type($value)));
6872
}

src/Internal/Transport/Router/DestroyWorkflow.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Temporal\Internal\Support\GarbageCollector;
1818
use Temporal\Internal\Workflow\Process\Process;
1919
use Temporal\Internal\Workflow\ProcessCollection;
20+
use Temporal\Worker\FeatureFlags;
2021
use Temporal\Worker\LoopInterface;
2122
use Temporal\Worker\Transport\Command\ServerRequestInterface;
2223

@@ -29,12 +30,14 @@ class DestroyWorkflow extends WorkflowProcessAwareRoute
2930
private const GC_TIMEOUT_SECONDS = 30;
3031

3132
private GarbageCollector $gc;
33+
private bool $throwDestructException;
3234

3335
public function __construct(
3436
ProcessCollection $running,
3537
protected LoopInterface $loop,
3638
) {
3739
$this->gc = new GarbageCollector(self::GC_THRESHOLD, self::GC_TIMEOUT_SECONDS);
40+
$this->throwDestructException = FeatureFlags::$throwDestructMemorizedInstanceException;
3841
parent::__construct($running);
3942
}
4043

@@ -51,7 +54,7 @@ public function kill(string $runId): array
5154
$process = $this->running
5255
->pull($runId, "Unable to kill workflow because workflow process #$runId was not found");
5356

54-
$process->cancel(new DestructMemorizedInstanceException());
57+
$this->throwDestructException and $process->cancel(new DestructMemorizedInstanceException());
5558
$this->loop->once(
5659
LoopInterface::ON_FINALLY,
5760
function () use ($process): void {

src/Internal/Workflow/Process/Scope.php

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -293,9 +293,17 @@ public function onAwait(Deferred $deferred): void
293293

294294
public function destroy(): void
295295
{
296-
$this->context->destroy();
297-
$this->scopeContext->destroy();
298-
unset($this->coroutine);
296+
$this->context?->destroy();
297+
$this->scopeContext?->destroy();
298+
unset(
299+
$this->coroutine,
300+
$this->context,
301+
$this->scopeContext,
302+
$this->deferred,
303+
$this->services,
304+
$this->onCancel,
305+
$this->onClose,
306+
);
299307
}
300308

301309
/**

src/Worker/FeatureFlags.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Temporal\Worker;
66

7+
use Temporal\Exception\DestructMemorizedInstanceException;
78
use Temporal\Workflow;
89

910
/**
@@ -48,4 +49,11 @@ final class FeatureFlags
4849
* @since SDK 2.16.0
4950
*/
5051
public static bool $cancelAbandonedChildWorkflows = true;
52+
53+
/**
54+
* Throw {@see DestructMemorizedInstanceException} when a Workflow instance is destructed.
55+
*
56+
* @since SDK 2.16.0
57+
*/
58+
public static bool $throwDestructMemorizedInstanceException = true;
5159
}

src/Workflow/WorkflowInfo.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Temporal\Client\ClientOptions;
1717
use Temporal\Common\CronSchedule;
1818
use Temporal\Common\Priority;
19+
use Temporal\Common\RetryOptions;
1920
use Temporal\Common\TypedSearchAttributes;
2021
use Temporal\Internal\Marshaller\Meta\Marshal;
2122
use Temporal\Internal\Marshaller\Type\ArrayType;
@@ -105,6 +106,12 @@ final class WorkflowInfo
105106
#[Marshal(name: 'ParentWorkflowNamespace')]
106107
public ?string $parentNamespace = null;
107108

109+
/**
110+
* @since SDK 2.16.0
111+
*/
112+
#[Marshal(name: 'RootWorkflowExecution', type: NullableType::class, of: WorkflowExecution::class)]
113+
public ?WorkflowExecution $rootExecution = null;
114+
108115
#[Marshal(name: 'ParentWorkflowExecution', type: NullableType::class, of: WorkflowExecution::class)]
109116
public ?WorkflowExecution $parentExecution = null;
110117

@@ -137,6 +144,12 @@ final class WorkflowInfo
137144
#[Marshal(name: 'Priority')]
138145
public Priority $priority;
139146

147+
/**
148+
* @since SDK 2.16.0
149+
*/
150+
#[Marshal(name: 'RetryPolicy')]
151+
public ?RetryOptions $retryOptions = null;
152+
140153
/**
141154
* WorkflowInfo constructor.
142155
*/
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Temporal\Tests\Acceptance\Extra\Activity\ActivityInfo;
6+
7+
use PHPUnit\Framework\Attributes\Test;
8+
use React\Promise\PromiseInterface;
9+
use Temporal\Activity;
10+
use Temporal\Client\WorkflowStubInterface;
11+
use Temporal\Common\RetryOptions;
12+
use Temporal\Tests\Acceptance\App\Attribute\Stub;
13+
use Temporal\Tests\Acceptance\App\TestCase;
14+
use Temporal\Workflow;
15+
use Temporal\Workflow\WorkflowInterface;
16+
use Temporal\Workflow\WorkflowMethod;
17+
18+
class ActivityInfoTest extends TestCase
19+
{
20+
#[Test]
21+
public static function retryPolicy(
22+
#[Stub('Extra_Activity_ActivityInfo', args: [TestWorkflow::ARG_RETRY_OPTIONS])]
23+
WorkflowStubInterface $stub,
24+
): void {
25+
self::markTestSkipped('See https://github.com/temporalio/sdk-php/issues/602');
26+
27+
$result = $stub->getResult(type: 'array');
28+
self::assertSame([
29+
"initial_interval" => ['seconds' => 1, 'nanos' => 0],
30+
"backoff_coefficient" => 3,
31+
"maximum_interval" => ['seconds' => 120, 'nanos' => 0],
32+
"maximum_attempts" => 20,
33+
"non_retryable_error_types" => [],
34+
], $result);
35+
}
36+
}
37+
38+
39+
#[WorkflowInterface]
40+
class TestWorkflow
41+
{
42+
public const ARG_RETRY_OPTIONS = 'retryPolicy';
43+
44+
#[WorkflowMethod(name: "Extra_Activity_ActivityInfo")]
45+
public function handle(string $arg)
46+
{
47+
return yield match ($arg) {
48+
self::ARG_RETRY_OPTIONS => $this->getRetryOptions(),
49+
};
50+
}
51+
52+
private function getRetryOptions(): PromiseInterface
53+
{
54+
return Workflow::newActivityStub(
55+
TestActivity::class,
56+
Activity\ActivityOptions::new()
57+
->withRetryOptions(
58+
RetryOptions::new()
59+
->withMaximumAttempts(20)
60+
->withBackoffCoefficient(3.0)
61+
->withInitialInterval('1 second')
62+
->withMaximumInterval('2 minutes'),
63+
)
64+
->withScheduleToCloseTimeout(10),
65+
)
66+
->retryOptions();
67+
}
68+
}
69+
70+
#[Activity\ActivityInterface(prefix: 'Extra_Activity_ActivityInfo.')]
71+
class TestActivity
72+
{
73+
#[Activity\ActivityMethod]
74+
public function retryOptions()
75+
{
76+
return Activity::getInfo()->retryOptions;
77+
}
78+
}

tests/Acceptance/Extra/Workflow/RootWorkflowExecutionTest.php

Lines changed: 0 additions & 55 deletions
This file was deleted.

0 commit comments

Comments
 (0)