Skip to content

Commit 4ce113b

Browse files
committed
feat: Add WorkflowContextInterface::getInstance();
Throw OutOfContextException if Workflow or Activity facades are called from a wrong context; Fix psalm issues;
1 parent dfa5fb0 commit 4ce113b

File tree

6 files changed

+39
-70
lines changed

6 files changed

+39
-70
lines changed

psalm-baseline.xml

Lines changed: 3 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -342,34 +342,11 @@
342342
<InvalidArgument>
343343
<code><![CDATA[$message->getDetails()]]></code>
344344
</InvalidArgument>
345-
<MismatchingDocblockParamType>
346-
<code><![CDATA[\ArrayAccess<int, Any>&RepeatedField]]></code>
347-
</MismatchingDocblockParamType>
348-
<MismatchingDocblockPropertyType>
349-
<code><![CDATA[\ArrayAccess<int, Any>&RepeatedField]]></code>
350-
</MismatchingDocblockPropertyType>
351-
<MismatchingDocblockReturnType>
352-
<code><![CDATA[\ArrayAccess<int, Any>&RepeatedField]]></code>
353-
</MismatchingDocblockReturnType>
354345
</file>
355346
<file src="src/Exception/Client/ServiceClientException.php">
356347
<ImplementedReturnTypeMismatch>
357348
<code><![CDATA[RepeatedField]]></code>
358349
</ImplementedReturnTypeMismatch>
359-
<InvalidReturnStatement>
360-
<code><![CDATA[$this->status->getDetails()]]></code>
361-
</InvalidReturnStatement>
362-
<InvalidReturnType>
363-
<code><![CDATA[RepeatedField]]></code>
364-
</InvalidReturnType>
365-
</file>
366-
<file src="src/Exception/Client/UnpackDetailsTrait.php">
367-
<RawObjectIteration>
368-
<code><![CDATA[$details]]></code>
369-
</RawObjectIteration>
370-
<UndefinedInterfaceMethod>
371-
<code><![CDATA[count]]></code>
372-
</UndefinedInterfaceMethod>
373350
</file>
374351
<file src="src/Exception/Client/WorkflowException.php">
375352
<UnsafeInstantiation>
@@ -827,9 +804,6 @@
827804
<NullableReturnStatement>
828805
<code><![CDATA[$mapper]]></code>
829806
</NullableReturnStatement>
830-
<PossibleRawObjectIteration>
831-
<code><![CDATA[$value]]></code>
832-
</PossibleRawObjectIteration>
833807
<PossiblyNullArgument>
834808
<code><![CDATA[$metadata->getDetails()]]></code>
835809
<code><![CDATA[$metadata->getSummary()]]></code>
@@ -997,13 +971,6 @@
997971
<code><![CDATA[$reflection->getName()]]></code>
998972
</PropertyTypeCoercion>
999973
</file>
1000-
<file src="src/Internal/Support/Facade.php">
1001-
<InvalidDocblock>
1002-
<code><![CDATA[object<T>|null]]></code>
1003-
<code><![CDATA[private static ?object $ctx = null;]]></code>
1004-
<code><![CDATA[public static function getCurrentContext(): object]]></code>
1005-
</InvalidDocblock>
1006-
</file>
1007974
<file src="src/Internal/Support/Inheritance.php">
1008975
<PossiblyFalseArgument>
1009976
<code><![CDATA[$implements]]></code>
@@ -1513,16 +1480,9 @@
15131480
</UnsafeInstantiation>
15141481
</file>
15151482
<file src="src/Workflow.php">
1516-
<InvalidReturnStatement>
1517-
<code><![CDATA[self::getCurrentContext()->newActivityStub($class, $options)]]></code>
1518-
<code><![CDATA[self::getCurrentContext()->registerQuery($queryType, $handler, $description)]]></code>
1519-
<code><![CDATA[self::getCurrentContext()->registerSignal($name, $handler, $description)]]></code>
1520-
</InvalidReturnStatement>
1521-
<InvalidReturnType>
1522-
<code><![CDATA[ScopedContextInterface]]></code>
1523-
<code><![CDATA[ScopedContextInterface]]></code>
1524-
<code><![CDATA[T]]></code>
1525-
</InvalidReturnType>
1483+
<UndefinedInterfaceMethod>
1484+
<code><![CDATA[getUpdateContext]]></code>
1485+
</UndefinedInterfaceMethod>
15261486
</file>
15271487
<file src="src/Workflow/ChildWorkflowOptions.php">
15281488
<PossiblyNullReference>

src/Activity.php

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,32 @@
1717
use Temporal\DataConverter\Type;
1818
use Temporal\DataConverter\ValuesInterface;
1919
use Temporal\Exception\OutOfContextException;
20+
use Temporal\Internal\Activity\ActivityContext;
2021
use Temporal\Internal\Support\Facade;
2122

22-
/**
23-
* @template-extends Facade<ActivityContextInterface>
24-
*/
2523
final class Activity extends Facade
2624
{
25+
/**
26+
* Get the current Activity context.
27+
* @throws OutOfContextException
28+
*/
29+
public static function getCurrentContext(): ActivityContextInterface
30+
{
31+
$ctx = parent::getCurrentContext();
32+
/** @var ActivityContext $ctx */
33+
$ctx::class === ActivityContext::class or throw new OutOfContextException(
34+
'The Activity facade can only be used in the context of an activity execution.',
35+
);
36+
return $ctx;
37+
}
38+
2739
/**
2840
* Returns information about current activity execution.
2941
*
3042
* @throws OutOfContextException in the absence of the activity execution context.
3143
*/
3244
public static function getInfo(): ActivityInfo
3345
{
34-
/** @var ActivityContextInterface $context */
3546
$context = self::getCurrentContext();
3647

3748
return $context->getInfo();
@@ -57,7 +68,6 @@ public static function getInfo(): ActivityInfo
5768
*/
5869
public static function getInput(): ValuesInterface
5970
{
60-
/** @var ActivityContextInterface $context */
6171
$context = self::getCurrentContext();
6272

6373
return $context->getInput();
@@ -72,7 +82,6 @@ public static function getInput(): ValuesInterface
7282
*/
7383
public static function hasHeartbeatDetails(): bool
7484
{
75-
/** @var ActivityContextInterface $context */
7685
$context = self::getCurrentContext();
7786

7887
return $context->hasHeartbeatDetails();
@@ -88,7 +97,6 @@ public static function hasHeartbeatDetails(): bool
8897
*/
8998
public static function getHeartbeatDetails($type = null): mixed
9099
{
91-
/** @var ActivityContextInterface $context */
92100
$context = self::getCurrentContext();
93101

94102
return $context->getLastHeartbeatDetails($type);
@@ -101,7 +109,6 @@ public static function getHeartbeatDetails($type = null): mixed
101109
*/
102110
public static function getCancellationDetails(): ?ActivityCancellationDetails
103111
{
104-
/** @var ActivityContextInterface $context */
105112
$context = self::getCurrentContext();
106113

107114
return $context->getCancellationDetails();
@@ -118,7 +125,6 @@ public static function getCancellationDetails(): ?ActivityCancellationDetails
118125
*/
119126
public static function doNotCompleteOnReturn(): void
120127
{
121-
/** @var ActivityContextInterface $context */
122128
$context = self::getCurrentContext();
123129

124130
$context->doNotCompleteOnReturn();
@@ -150,7 +156,6 @@ public static function doNotCompleteOnReturn(): void
150156
*/
151157
public static function heartbeat($details): void
152158
{
153-
/** @var ActivityContextInterface $context */
154159
$context = self::getCurrentContext();
155160

156161
$context->heartbeat($details);
@@ -161,7 +166,6 @@ public static function heartbeat($details): void
161166
*/
162167
public static function getInstance(): object
163168
{
164-
/** @var ActivityContextInterface $context */
165169
$context = self::getCurrentContext();
166170

167171
return $context->getInstance();

src/Internal/Support/Facade.php

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

1414
use Temporal\Exception\OutOfContextException;
1515

16-
/**
17-
* @template T of object
18-
*/
1916
abstract class Facade
2017
{
2118
/**
@@ -26,9 +23,6 @@ abstract class Facade
2623
'from the currently running process'
2724
;
2825

29-
/**
30-
* @var object<T>|null
31-
*/
3226
private static ?object $ctx = null;
3327

3428
/**
@@ -40,7 +34,6 @@ private function __construct()
4034
}
4135

4236
/**
43-
* @param object<T>|null $ctx
4437
* @internal
4538
*/
4639
public static function setCurrentContext(?object $ctx): void
@@ -49,7 +42,6 @@ public static function setCurrentContext(?object $ctx): void
4942
}
5043

5144
/**
52-
* @return object<T>
5345
* @throws OutOfContextException
5446
*/
5547
public static function getCurrentContext(): object

src/Internal/Transport/Router/InvokeActivity.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ static function (ActivityInput $input) use ($handler, $context): mixed {
101101
'handleActivityInbound',
102102
)(new ActivityInput($context->getInput(), $context->getHeader()));
103103

104+
/** @var ActivityContext $context */
104105
$context = Activity::getCurrentContext();
105106
if ($context->isDoNotCompleteOnReturn()) {
106107
$resolver->reject(DoNotCompleteOnResultException::create());

src/Workflow.php

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,18 +45,28 @@
4545
*
4646
* This is main class you can use in your workflow code.
4747
*
48-
* @method static ScopeContext getCurrentContext() Get current workflow context.
49-
*
5048
* @psalm-import-type TypeEnum from Type
5149
* @psalm-import-type DateIntervalValue from DateInterval
5250
* @see DateInterval
53-
*
54-
* @template-extends Facade<ScopedContextInterface>
5551
*/
5652
final class Workflow extends Facade
5753
{
5854
public const DEFAULT_VERSION = -1;
5955

56+
/**
57+
* Get the current Workflow context.
58+
* @throws OutOfContextException
59+
*/
60+
public static function getCurrentContext(): ScopedContextInterface
61+
{
62+
$ctx = parent::getCurrentContext();
63+
/** @var ScopeContext $ctx */
64+
$ctx::class === ScopeContext::class or throw new OutOfContextException(
65+
'The Workflow facade can be used only inside workflow code.',
66+
);
67+
return $ctx;
68+
}
69+
6070
/**
6171
* Returns current datetime.
6272
*
@@ -995,7 +1005,6 @@ public static function getStackTrace(): string
9951005
*/
9961006
public static function allHandlersFinished(): bool
9971007
{
998-
/** @var ScopedContextInterface $context */
9991008
$context = self::getCurrentContext();
10001009

10011010
return $context->allHandlersFinished();
@@ -1081,7 +1090,6 @@ public static function upsertTypedSearchAttributes(SearchAttributeUpdate ...$upd
10811090
*/
10821091
public static function uuid(): PromiseInterface
10831092
{
1084-
/** @var ScopedContextInterface $context */
10851093
$context = self::getCurrentContext();
10861094

10871095
return $context->uuid();
@@ -1094,7 +1102,6 @@ public static function uuid(): PromiseInterface
10941102
*/
10951103
public static function uuid4(): PromiseInterface
10961104
{
1097-
/** @var ScopedContextInterface $context */
10981105
$context = self::getCurrentContext();
10991106

11001107
return $context->uuid4();
@@ -1111,7 +1118,6 @@ public static function uuid4(): PromiseInterface
11111118
*/
11121119
public static function uuid7(?\DateTimeInterface $dateTime = null): PromiseInterface
11131120
{
1114-
/** @var ScopedContextInterface $context */
11151121
$context = self::getCurrentContext();
11161122

11171123
return $context->uuid7($dateTime);

src/Workflow/WorkflowContextInterface.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use Temporal\Common\SearchAttributes\SearchAttributeUpdate;
2020
use Temporal\DataConverter\Type;
2121
use Temporal\DataConverter\ValuesInterface;
22+
use Temporal\Exception\OutOfContextException;
2223
use Temporal\Internal\Support\DateInterval;
2324
use Temporal\Worker\Transport\Command\RequestInterface;
2425
use Temporal\Worker\Environment\EnvironmentInterface;
@@ -440,4 +441,9 @@ public function uuid7(?\DateTimeInterface $dateTime = null): PromiseInterface;
440441
* Logs in replay mode are omitted unless {@see WorkerOptions::$enableLoggingInReplay} is set to true.
441442
*/
442443
public function getLogger(): LoggerInterface;
444+
445+
/**
446+
* Get the currently running Workflow instance.
447+
*/
448+
public function getInstance(): object;
443449
}

0 commit comments

Comments
 (0)