From 9299403bca2b2778db9e7647c954aa66cff85b48 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Mon, 16 Feb 2026 11:39:27 +0400 Subject: [PATCH 1/5] feat: implement workflow current details --- src/Internal/Transport/Router/InvokeQuery.php | 14 +++-- src/Internal/Workflow/ScopeContext.php | 1 + src/Internal/Workflow/WorkflowContext.php | 17 +++++ src/Workflow.php | 16 +++++ src/Workflow/WorkflowContextInterface.php | 10 +++ .../Extra/Workflow/WorkflowMetadataTest.php | 62 +++++++++++++++++++ 6 files changed, 114 insertions(+), 6 deletions(-) create mode 100644 tests/Acceptance/Extra/Workflow/WorkflowMetadataTest.php diff --git a/src/Internal/Transport/Router/InvokeQuery.php b/src/Internal/Transport/Router/InvokeQuery.php index 30ba6b96..aa31fce9 100644 --- a/src/Internal/Transport/Router/InvokeQuery.php +++ b/src/Internal/Transport/Router/InvokeQuery.php @@ -122,12 +122,14 @@ private function workflowMetadata(Deferred $resolver, WorkflowContext $context): static function () use ($resolver, $context): void { try { $result = EncodedValues::fromValues([ - (new WorkflowMetadata())->setDefinition( - (new WorkflowDefinition()) - ->setQueryDefinitions($context->getQueryDispatcher()->getQueryHandlers()) - ->setSignalDefinitions($context->getSignalDispatcher()->getSignalHandlers()) - ->setUpdateDefinitions($context->getUpdateDispatcher()->getUpdateHandlers()), - ), + (new WorkflowMetadata()) + ->setDefinition( + (new WorkflowDefinition()) + ->setQueryDefinitions($context->getQueryDispatcher()->getQueryHandlers()) + ->setSignalDefinitions($context->getSignalDispatcher()->getSignalHandlers()) + ->setUpdateDefinitions($context->getUpdateDispatcher()->getUpdateHandlers()), + ) + ->setCurrentDetails($context->getCurrentDetails()), ]); $resolver->resolve($result); diff --git a/src/Internal/Workflow/ScopeContext.php b/src/Internal/Workflow/ScopeContext.php index bff6743a..b9a3ebab 100644 --- a/src/Internal/Workflow/ScopeContext.php +++ b/src/Internal/Workflow/ScopeContext.php @@ -57,6 +57,7 @@ public static function fromWorkflowContext( $ctx->readonly = $context->readonly; $ctx->continueAsNew = $context->continueAsNew; $ctx->trace = &$context->trace; + $ctx->currentDetails = &$context->currentDetails; return $ctx; } diff --git a/src/Internal/Workflow/WorkflowContext.php b/src/Internal/Workflow/WorkflowContext.php index 26e8fb84..74206f37 100644 --- a/src/Internal/Workflow/WorkflowContext.php +++ b/src/Internal/Workflow/WorkflowContext.php @@ -99,6 +99,7 @@ class WorkflowContext implements WorkflowContextInterface, HeaderCarrier, Destro protected array $trace = []; protected bool $continueAsNew = false; protected bool $readonly = true; + protected ?string $currentDetails = null; /** @var Pipeline */ private Pipeline $requestInterceptor; @@ -790,4 +791,20 @@ protected function recordTrace(): void { $this->readonly or $this->trace = \debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS); } + + /** + * Get the current details of the workflow execution. + */ + public function getCurrentDetails(): ?string + { + return $this->currentDetails; + } + + /** + * Set the current details of the workflow execution. + */ + public function setCurrentDetails(?string $details): void + { + $this->currentDetails = $details; + } } diff --git a/src/Workflow.php b/src/Workflow.php index 5712ef60..e8927f88 100644 --- a/src/Workflow.php +++ b/src/Workflow.php @@ -604,6 +604,22 @@ public static function timer($interval, ?TimerOptions $options = null): PromiseI return self::getCurrentContext()->timer($interval, $options); } + /** + * Get the current details of the workflow execution. + */ + public static function getCurrentDetails(): ?string + { + return self::getCurrentContext()->getCurrentDetails(); + } + + /** + * Set the current details of the workflow execution. + */ + public static function setCurrentDetails(?string $details): void + { + self::getCurrentContext()->setCurrentDetails($details); + } + /** * Completes the current workflow execution atomically and starts a new execution with the same Workflow Id. * diff --git a/src/Workflow/WorkflowContextInterface.php b/src/Workflow/WorkflowContextInterface.php index 945eda1c..30548a8f 100644 --- a/src/Workflow/WorkflowContextInterface.php +++ b/src/Workflow/WorkflowContextInterface.php @@ -445,4 +445,14 @@ public function getLogger(): LoggerInterface; * Get the currently running Workflow instance. */ public function getInstance(): object; + + /** + * Get the current details of the workflow execution. + */ + public function getCurrentDetails(): ?string; + + /** + * Set the current details of the workflow execution. + */ + public function setCurrentDetails(?string $details): void; } diff --git a/tests/Acceptance/Extra/Workflow/WorkflowMetadataTest.php b/tests/Acceptance/Extra/Workflow/WorkflowMetadataTest.php new file mode 100644 index 00000000..35fda392 --- /dev/null +++ b/tests/Acceptance/Extra/Workflow/WorkflowMetadataTest.php @@ -0,0 +1,62 @@ +query('getCurrentDetails')->getValue(0); + if ($currentDetails !== null) { + break; + } + } while (\microtime(true) < $deadline); + + $stub->signal('exit'); + $this->assertSame("Cooking workflow from test", $currentDetails); + } +} + +#[WorkflowInterface] +class TestWorkflow +{ + private bool $exit = false; + + #[WorkflowMethod(name: "Extra_Workflow_WorkflowMetadata")] + public function handle(string $payload) + { + Workflow::setCurrentDetails("Cooking workflow " . $payload); + + yield Workflow::await(fn() => $this->exit); + } + + /** + * @return null|non-empty-string + */ + #[Workflow\QueryMethod] + public function getCurrentDetails(): ?string + { + return Workflow::getCurrentDetails(); + } + + #[Workflow\SignalMethod] + public function exit(): void + { + $this->exit = true; + } +} From ea7d030ec11ffbd156fd7b898deac9bb0fef02a7 Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 16 Feb 2026 07:39:56 +0000 Subject: [PATCH 2/5] style(php-cs-fixer): fix coding standards --- src/Internal/Workflow/WorkflowContext.php | 32 +++++++++++------------ 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/Internal/Workflow/WorkflowContext.php b/src/Internal/Workflow/WorkflowContext.php index 74206f37..5fc887cb 100644 --- a/src/Internal/Workflow/WorkflowContext.php +++ b/src/Internal/Workflow/WorkflowContext.php @@ -724,6 +724,22 @@ public function getUpdateDispatcher(): UpdateDispatcher return $this->updateDispatcher; } + /** + * Get the current details of the workflow execution. + */ + public function getCurrentDetails(): ?string + { + return $this->currentDetails; + } + + /** + * Set the current details of the workflow execution. + */ + public function setCurrentDetails(?string $details): void + { + $this->currentDetails = $details; + } + protected function awaitRequest(callable|Mutex|PromiseInterface ...$conditions): PromiseInterface { $result = []; @@ -791,20 +807,4 @@ protected function recordTrace(): void { $this->readonly or $this->trace = \debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS); } - - /** - * Get the current details of the workflow execution. - */ - public function getCurrentDetails(): ?string - { - return $this->currentDetails; - } - - /** - * Set the current details of the workflow execution. - */ - public function setCurrentDetails(?string $details): void - { - $this->currentDetails = $details; - } } From d8958c7de167acb2e9a0a4008f1b556fc9fea81f Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Mon, 16 Feb 2026 12:02:42 +0400 Subject: [PATCH 3/5] feat: improve error message --- src/DataConverter/ProtoJsonConverter.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/DataConverter/ProtoJsonConverter.php b/src/DataConverter/ProtoJsonConverter.php index 34daf659..493f1dde 100644 --- a/src/DataConverter/ProtoJsonConverter.php +++ b/src/DataConverter/ProtoJsonConverter.php @@ -50,7 +50,13 @@ public function toPayload($value): ?Payload public function fromPayload(Payload $payload, Type $type) { if (!$type->isClass()) { - throw new DataConverterException('Unable to decode value using protobuf converter - '); + throw new DataConverterException( + \sprintf( + 'Unable to decode value using "%s" encoding converter: resulting type must be a class, "%s" given', + $this->getEncodingType(), + $type->getName(), + ), + ); } try { From e5f8649ffcc2db4dedce919496cae0bb4e57cb31 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Mon, 16 Feb 2026 12:02:53 +0400 Subject: [PATCH 4/5] feat: rewrite test --- src/Internal/Transport/Router/InvokeQuery.php | 2 +- .../Extra/Workflow/WorkflowMetadataTest.php | 18 ++++++++---------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/Internal/Transport/Router/InvokeQuery.php b/src/Internal/Transport/Router/InvokeQuery.php index aa31fce9..b19580b7 100644 --- a/src/Internal/Transport/Router/InvokeQuery.php +++ b/src/Internal/Transport/Router/InvokeQuery.php @@ -129,7 +129,7 @@ static function () use ($resolver, $context): void { ->setSignalDefinitions($context->getSignalDispatcher()->getSignalHandlers()) ->setUpdateDefinitions($context->getUpdateDispatcher()->getUpdateHandlers()), ) - ->setCurrentDetails($context->getCurrentDetails()), + ->setCurrentDetails((string) $context->getCurrentDetails()), ]); $resolver->resolve($result); diff --git a/tests/Acceptance/Extra/Workflow/WorkflowMetadataTest.php b/tests/Acceptance/Extra/Workflow/WorkflowMetadataTest.php index 35fda392..4a90e47b 100644 --- a/tests/Acceptance/Extra/Workflow/WorkflowMetadataTest.php +++ b/tests/Acceptance/Extra/Workflow/WorkflowMetadataTest.php @@ -5,7 +5,7 @@ namespace Temporal\Tests\Acceptance\Extra\Workflow\WorkflowMetadata; use PHPUnit\Framework\Attributes\Test; -use Temporal\Client\WorkflowClientInterface; +use Temporal\Api\Sdk\V1\WorkflowMetadata; use Temporal\Client\WorkflowStubInterface; use Temporal\Tests\Acceptance\App\Attribute\Stub; use Temporal\Tests\Acceptance\App\TestCase; @@ -16,19 +16,17 @@ class WorkflowMetadataTest extends TestCase { #[Test] - public function updateHandlersWithOneCall( + public function metadataQuery( #[Stub('Extra_Workflow_WorkflowMetadata', args: ["from test"])] WorkflowStubInterface $stub, ): void { - $deadline = \microtime(true) + 5.0; // 5-second timeout - do { - $currentDetails = $stub->query('getCurrentDetails')->getValue(0); - if ($currentDetails !== null) { - break; - } - } while (\microtime(true) < $deadline); + $values = $stub->query('__temporal_workflow_metadata'); + /** + * @var WorkflowMetadata|null $metadata + */ + $metadata = $values->getValue(0, WorkflowMetadata::class); $stub->signal('exit'); - $this->assertSame("Cooking workflow from test", $currentDetails); + $this->assertSame("Cooking workflow from test", $metadata->getCurrentDetails()); } } From 396d9790e3571419c147e1f23adaf352e6320eee Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Mon, 16 Feb 2026 12:38:14 +0400 Subject: [PATCH 5/5] feat: psalm:baseline --- psalm-baseline.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 29cf6ce4..fdae7573 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1178,6 +1178,7 @@ + currentDetails = &$context->currentDetails]]> trace = &$context->trace]]>