diff --git a/psalm-baseline.xml b/psalm-baseline.xml
index d2e6b6a4..1c68e783 100644
--- a/psalm-baseline.xml
+++ b/psalm-baseline.xml
@@ -342,34 +342,11 @@
getDetails()]]>
-
- &RepeatedField]]>
-
-
- &RepeatedField]]>
-
-
- &RepeatedField]]>
-
-
- status->getDetails()]]>
-
-
-
-
-
-
-
-
-
-
-
-
@@ -827,9 +804,6 @@
-
-
-
getDetails()]]>
getSummary()]]>
@@ -997,13 +971,6 @@
getName()]]>
-
-
- |null]]>
-
-
-
-
@@ -1513,16 +1480,9 @@
-
- newActivityStub($class, $options)]]>
- registerQuery($queryType, $handler, $description)]]>
- registerSignal($name, $handler, $description)]]>
-
-
-
-
-
-
+
+
+
diff --git a/src/Activity.php b/src/Activity.php
index fe5886e6..9b9d069d 100644
--- a/src/Activity.php
+++ b/src/Activity.php
@@ -17,13 +17,25 @@
use Temporal\DataConverter\Type;
use Temporal\DataConverter\ValuesInterface;
use Temporal\Exception\OutOfContextException;
+use Temporal\Internal\Activity\ActivityContext;
use Temporal\Internal\Support\Facade;
-/**
- * @template-extends Facade
- */
final class Activity extends Facade
{
+ /**
+ * Get the current Activity context.
+ * @throws OutOfContextException
+ */
+ public static function getCurrentContext(): ActivityContextInterface
+ {
+ $ctx = parent::getCurrentContext();
+ /** @var ActivityContext $ctx */
+ $ctx::class === ActivityContext::class or throw new OutOfContextException(
+ 'The Activity facade can only be used in the context of an activity execution.',
+ );
+ return $ctx;
+ }
+
/**
* Returns information about current activity execution.
*
@@ -31,7 +43,6 @@ final class Activity extends Facade
*/
public static function getInfo(): ActivityInfo
{
- /** @var ActivityContextInterface $context */
$context = self::getCurrentContext();
return $context->getInfo();
@@ -57,7 +68,6 @@ public static function getInfo(): ActivityInfo
*/
public static function getInput(): ValuesInterface
{
- /** @var ActivityContextInterface $context */
$context = self::getCurrentContext();
return $context->getInput();
@@ -72,7 +82,6 @@ public static function getInput(): ValuesInterface
*/
public static function hasHeartbeatDetails(): bool
{
- /** @var ActivityContextInterface $context */
$context = self::getCurrentContext();
return $context->hasHeartbeatDetails();
@@ -88,7 +97,6 @@ public static function hasHeartbeatDetails(): bool
*/
public static function getHeartbeatDetails($type = null): mixed
{
- /** @var ActivityContextInterface $context */
$context = self::getCurrentContext();
return $context->getLastHeartbeatDetails($type);
@@ -101,7 +109,6 @@ public static function getHeartbeatDetails($type = null): mixed
*/
public static function getCancellationDetails(): ?ActivityCancellationDetails
{
- /** @var ActivityContextInterface $context */
$context = self::getCurrentContext();
return $context->getCancellationDetails();
@@ -118,7 +125,6 @@ public static function getCancellationDetails(): ?ActivityCancellationDetails
*/
public static function doNotCompleteOnReturn(): void
{
- /** @var ActivityContextInterface $context */
$context = self::getCurrentContext();
$context->doNotCompleteOnReturn();
@@ -150,7 +156,6 @@ public static function doNotCompleteOnReturn(): void
*/
public static function heartbeat($details): void
{
- /** @var ActivityContextInterface $context */
$context = self::getCurrentContext();
$context->heartbeat($details);
@@ -161,7 +166,6 @@ public static function heartbeat($details): void
*/
public static function getInstance(): object
{
- /** @var ActivityContextInterface $context */
$context = self::getCurrentContext();
return $context->getInstance();
diff --git a/src/Internal/Support/Facade.php b/src/Internal/Support/Facade.php
index dea6ef85..bf13a67e 100644
--- a/src/Internal/Support/Facade.php
+++ b/src/Internal/Support/Facade.php
@@ -13,9 +13,6 @@
use Temporal\Exception\OutOfContextException;
-/**
- * @template T of object
- */
abstract class Facade
{
/**
@@ -26,9 +23,6 @@ abstract class Facade
'from the currently running process'
;
- /**
- * @var object|null
- */
private static ?object $ctx = null;
/**
@@ -40,7 +34,6 @@ private function __construct()
}
/**
- * @param object|null $ctx
* @internal
*/
public static function setCurrentContext(?object $ctx): void
@@ -49,7 +42,6 @@ public static function setCurrentContext(?object $ctx): void
}
/**
- * @return object
* @throws OutOfContextException
*/
public static function getCurrentContext(): object
diff --git a/src/Internal/Transport/Router/InvokeActivity.php b/src/Internal/Transport/Router/InvokeActivity.php
index 1ec3c4e8..ffa1f537 100644
--- a/src/Internal/Transport/Router/InvokeActivity.php
+++ b/src/Internal/Transport/Router/InvokeActivity.php
@@ -101,6 +101,7 @@ static function (ActivityInput $input) use ($handler, $context): mixed {
'handleActivityInbound',
)(new ActivityInput($context->getInput(), $context->getHeader()));
+ /** @var ActivityContext $context */
$context = Activity::getCurrentContext();
if ($context->isDoNotCompleteOnReturn()) {
$resolver->reject(DoNotCompleteOnResultException::create());
diff --git a/src/Internal/Transport/Router/StartWorkflow.php b/src/Internal/Transport/Router/StartWorkflow.php
index d0b9dd50..97edf8b2 100644
--- a/src/Internal/Transport/Router/StartWorkflow.php
+++ b/src/Internal/Transport/Router/StartWorkflow.php
@@ -25,7 +25,6 @@
use Temporal\Internal\Workflow\WorkflowContext;
use Temporal\Worker\FeatureFlags;
use Temporal\Worker\Transport\Command\ServerRequestInterface;
-use Temporal\Workflow;
use Temporal\Workflow\WorkflowInfo;
final class StartWorkflow extends Route
@@ -90,7 +89,6 @@ public function handle(ServerRequestInterface $request, array $headers, Deferred
);
$runId = $request->getID();
- Workflow::setCurrentContext($context);
$process = new Process($this->services, $runId, $instance);
$this->services->running->add($process);
$resolver->resolve(EncodedValues::fromValues([null]));
diff --git a/src/Internal/Workflow/ActivityStub.php b/src/Internal/Workflow/ActivityStub.php
index 980455f0..4ecc930a 100644
--- a/src/Internal/Workflow/ActivityStub.php
+++ b/src/Internal/Workflow/ActivityStub.php
@@ -70,9 +70,6 @@ public function execute(
protected function request(RequestInterface $request): PromiseInterface
{
- /** @var Workflow\WorkflowContextInterface $context */
- $context = Workflow::getCurrentContext();
-
- return $context->request($request);
+ return Workflow::getCurrentContext()->request($request);
}
}
diff --git a/src/Internal/Workflow/ChildWorkflowStub.php b/src/Internal/Workflow/ChildWorkflowStub.php
index 2aa21b06..2bc9fb5b 100644
--- a/src/Internal/Workflow/ChildWorkflowStub.php
+++ b/src/Internal/Workflow/ChildWorkflowStub.php
@@ -125,10 +125,7 @@ function (WorkflowExecution $execution) use ($name, $args) {
protected function request(RequestInterface $request, bool $cancellable = true): PromiseInterface
{
- /** @var Workflow\WorkflowContextInterface $context */
- $context = Workflow::getCurrentContext();
-
- return $context->request($request, cancellable: $cancellable);
+ return Workflow::getCurrentContext()->request($request, cancellable: $cancellable);
}
private function getOptionArray(): array
diff --git a/src/Internal/Workflow/ExternalWorkflowStub.php b/src/Internal/Workflow/ExternalWorkflowStub.php
index 9f047fb7..75b4ff37 100644
--- a/src/Internal/Workflow/ExternalWorkflowStub.php
+++ b/src/Internal/Workflow/ExternalWorkflowStub.php
@@ -77,7 +77,6 @@ public function cancel(): PromiseInterface
private function request(RequestInterface $request): PromiseInterface
{
// todo intercept
- /** @var Workflow\WorkflowContextInterface $context */
$context = Workflow::getCurrentContext();
return $context->request($request);
diff --git a/src/Workflow.php b/src/Workflow.php
index 1772f59a..06bbb4be 100644
--- a/src/Workflow.php
+++ b/src/Workflow.php
@@ -23,7 +23,6 @@
use Temporal\Exception\Failure\CanceledFailure;
use Temporal\Exception\OutOfContextException;
use Temporal\Internal\Support\Facade;
-use Temporal\Internal\Workflow\ScopeContext;
use Temporal\Workflow\ActivityStubInterface;
use Temporal\Workflow\CancellationScopeInterface;
use Temporal\Workflow\ChildWorkflowOptions;
@@ -45,18 +44,27 @@
*
* This is main class you can use in your workflow code.
*
- * @method static ScopeContext getCurrentContext() Get current workflow context.
- *
* @psalm-import-type TypeEnum from Type
* @psalm-import-type DateIntervalValue from DateInterval
* @see DateInterval
- *
- * @template-extends Facade
*/
final class Workflow extends Facade
{
public const DEFAULT_VERSION = -1;
+ /**
+ * Get the current Workflow context.
+ * @throws OutOfContextException
+ */
+ public static function getCurrentContext(): WorkflowContextInterface
+ {
+ $ctx = parent::getCurrentContext();
+ $ctx instanceof WorkflowContextInterface or throw new OutOfContextException(
+ 'The Workflow facade can be used only inside workflow code.',
+ );
+ return $ctx;
+ }
+
/**
* Returns current datetime.
*
@@ -192,7 +200,9 @@ public static function getInput(): ValuesInterface
*/
public static function async(callable $task): CancellationScopeInterface
{
- return self::getCurrentContext()->async($task);
+ $ctx = self::getCurrentContext();
+ \assert($ctx instanceof ScopedContextInterface);
+ return $ctx->async($task);
}
/**
@@ -244,7 +254,9 @@ public static function async(callable $task): CancellationScopeInterface
*/
public static function asyncDetached(callable $task): CancellationScopeInterface
{
- return self::getCurrentContext()->asyncDetached($task);
+ $ctx = self::getCurrentContext();
+ \assert($ctx instanceof ScopedContextInterface);
+ return $ctx->asyncDetached($task);
}
/**
@@ -352,7 +364,9 @@ public static function registerQuery(
callable $handler,
string $description = '',
): ScopedContextInterface {
- return self::getCurrentContext()->registerQuery($queryType, $handler, $description);
+ $ctx = self::getCurrentContext();
+ \assert($ctx instanceof ScopedContextInterface);
+ return $ctx->registerQuery($queryType, $handler, $description);
}
/**
@@ -372,7 +386,9 @@ public static function registerQuery(
*/
public static function registerSignal(string $name, callable $handler, string $description = ''): ScopedContextInterface
{
- return self::getCurrentContext()->registerSignal($name, $handler, $description);
+ $ctx = self::getCurrentContext();
+ \assert($ctx instanceof ScopedContextInterface);
+ return $ctx->registerSignal($name, $handler, $description);
}
/**
@@ -491,7 +507,9 @@ public static function registerUpdate(
?callable $validator = null,
string $description = '',
): ScopedContextInterface {
- return self::getCurrentContext()->registerUpdate($name, $handler, $validator, $description);
+ $ctx = self::getCurrentContext();
+ \assert($ctx instanceof ScopedContextInterface);
+ return $ctx->registerUpdate($name, $handler, $validator, $description);
}
/**
@@ -995,7 +1013,6 @@ public static function getStackTrace(): string
*/
public static function allHandlersFinished(): bool
{
- /** @var ScopedContextInterface $context */
$context = self::getCurrentContext();
return $context->allHandlersFinished();
@@ -1081,7 +1098,6 @@ public static function upsertTypedSearchAttributes(SearchAttributeUpdate ...$upd
*/
public static function uuid(): PromiseInterface
{
- /** @var ScopedContextInterface $context */
$context = self::getCurrentContext();
return $context->uuid();
@@ -1094,7 +1110,6 @@ public static function uuid(): PromiseInterface
*/
public static function uuid4(): PromiseInterface
{
- /** @var ScopedContextInterface $context */
$context = self::getCurrentContext();
return $context->uuid4();
@@ -1111,7 +1126,6 @@ public static function uuid4(): PromiseInterface
*/
public static function uuid7(?\DateTimeInterface $dateTime = null): PromiseInterface
{
- /** @var ScopedContextInterface $context */
$context = self::getCurrentContext();
return $context->uuid7($dateTime);
diff --git a/src/Workflow/WorkflowContextInterface.php b/src/Workflow/WorkflowContextInterface.php
index e0dd1c47..945eda1c 100644
--- a/src/Workflow/WorkflowContextInterface.php
+++ b/src/Workflow/WorkflowContextInterface.php
@@ -440,4 +440,9 @@ public function uuid7(?\DateTimeInterface $dateTime = null): PromiseInterface;
* Logs in replay mode are omitted unless {@see WorkerOptions::$enableLoggingInReplay} is set to true.
*/
public function getLogger(): LoggerInterface;
+
+ /**
+ * Get the currently running Workflow instance.
+ */
+ public function getInstance(): object;
}