From 4d90c32474ef070398dc9c184208891022f4b5cd Mon Sep 17 00:00:00 2001 From: roxblnfk Date: Thu, 23 May 2024 01:34:16 +0400 Subject: [PATCH 1/6] chore: simplify internal types --- .../Dispatcher/AutowiredPayloads.php | 8 ++------ .../Declaration/Dispatcher/Dispatcher.php | 7 +------ .../Dispatcher/DispatcherInterface.php | 10 ++++------ src/Internal/Declaration/Instance.php | 17 +++++------------ src/Internal/Declaration/InstanceInterface.php | 5 +---- src/Internal/Declaration/WorkflowInstance.php | 6 +----- .../WorkflowInstance/SignalQueue.php | 4 ++-- .../Declaration/WorkflowInstanceInterface.php | 6 ++++-- src/Internal/Marshaller/Type/ArrayType.php | 5 ++--- tests/Unit/Worker/AutowiringTestCase.php | 15 --------------- 10 files changed, 22 insertions(+), 61 deletions(-) diff --git a/src/Internal/Declaration/Dispatcher/AutowiredPayloads.php b/src/Internal/Declaration/Dispatcher/AutowiredPayloads.php index f7a5f11e..e659c933 100644 --- a/src/Internal/Declaration/Dispatcher/AutowiredPayloads.php +++ b/src/Internal/Declaration/Dispatcher/AutowiredPayloads.php @@ -16,15 +16,11 @@ /** * @psalm-type FunctionExecutor = \Closure(object|null, array): mixed + * @internal */ class AutowiredPayloads extends Dispatcher { - /** - * @param object|null $ctx - * @param ValuesInterface $values - * @return mixed - */ - public function dispatchValues(?object $ctx, ValuesInterface $values) + public function dispatchValues(object $ctx, ValuesInterface $values): mixed { $arguments = []; for ($i = 0; $i < $values->count(); $i++) { diff --git a/src/Internal/Declaration/Dispatcher/Dispatcher.php b/src/Internal/Declaration/Dispatcher/Dispatcher.php index e50bd8ef..7274e9be 100644 --- a/src/Internal/Declaration/Dispatcher/Dispatcher.php +++ b/src/Internal/Declaration/Dispatcher/Dispatcher.php @@ -95,12 +95,7 @@ public function getArgumentTypes(): array return $this->types; } - /** - * @param object|null $ctx - * @param array $arguments - * @return mixed - */ - public function dispatch(?object $ctx, array $arguments) + public function dispatch(object $ctx, array $arguments): mixed { return ($this->executor)($ctx, $arguments); } diff --git a/src/Internal/Declaration/Dispatcher/DispatcherInterface.php b/src/Internal/Declaration/Dispatcher/DispatcherInterface.php index 3a60fef5..695c7ec9 100644 --- a/src/Internal/Declaration/Dispatcher/DispatcherInterface.php +++ b/src/Internal/Declaration/Dispatcher/DispatcherInterface.php @@ -11,14 +11,12 @@ namespace Temporal\Internal\Declaration\Dispatcher; +/** + * @internal + */ interface DispatcherInterface { - /** - * @param object|null $ctx - * @param array $arguments - * @return mixed - */ - public function dispatch(?object $ctx, array $arguments); + public function dispatch(object $ctx, array $arguments): mixed; /** * @return array<\ReflectionType> diff --git a/src/Internal/Declaration/Instance.php b/src/Internal/Declaration/Instance.php index 44394068..f34b1d7d 100644 --- a/src/Internal/Declaration/Instance.php +++ b/src/Internal/Declaration/Instance.php @@ -21,18 +21,15 @@ */ abstract class Instance implements InstanceInterface { - protected object $context; /** * @var \Closure(ValuesInterface): mixed */ private \Closure $handler; - /** - * @param Prototype $prototype - * @param object $context - */ - public function __construct(Prototype $prototype, object $context) - { + public function __construct( + Prototype $prototype, + protected readonly object $context, + ) { $handler = $prototype->getHandler(); if ($handler === null) { @@ -42,14 +39,10 @@ public function __construct(Prototype $prototype, object $context) )); } - $this->context = $context; $this->handler = $this->createHandler($handler); } - /** - * @return object|null - */ - public function getContext(): ?object + public function getContext(): object { return $this->context; } diff --git a/src/Internal/Declaration/InstanceInterface.php b/src/Internal/Declaration/InstanceInterface.php index b8f23c99..d58c714d 100644 --- a/src/Internal/Declaration/InstanceInterface.php +++ b/src/Internal/Declaration/InstanceInterface.php @@ -23,8 +23,5 @@ interface InstanceInterface */ public function getHandler(): callable; - /** - * @return object|null - */ - public function getContext(): ?object; + public function getContext(): object; } diff --git a/src/Internal/Declaration/WorkflowInstance.php b/src/Internal/Declaration/WorkflowInstance.php index bbe3ca9b..7c4e0bee 100644 --- a/src/Internal/Declaration/WorkflowInstance.php +++ b/src/Internal/Declaration/WorkflowInstance.php @@ -141,7 +141,7 @@ public function setUpdateValidator(\Closure $validator): self */ public function initConstructor(): void { - if (method_exists($this->context, '__construct')) { + if (\method_exists($this->context, '__construct')) { $this->context->__construct(); } } @@ -234,10 +234,6 @@ public function getUpdateHandlerNames(): array return \array_keys($this->updateHandlers); } - /** - * @param string $name - * @return \Closure - */ public function getSignalHandler(string $name): \Closure { return fn (ValuesInterface $values) => $this->signalQueue->push($name, $values); diff --git a/src/Internal/Declaration/WorkflowInstance/SignalQueue.php b/src/Internal/Declaration/WorkflowInstance/SignalQueue.php index afa98fbf..b899a50a 100644 --- a/src/Internal/Declaration/WorkflowInstance/SignalQueue.php +++ b/src/Internal/Declaration/WorkflowInstance/SignalQueue.php @@ -36,7 +36,7 @@ final class SignalQueue private $onSignal; /** - * @param string $signal + * @param non-empty-string $signal * @param ValuesInterface $values */ public function push(string $signal, ValuesInterface $values): void @@ -60,7 +60,7 @@ public function onSignal(callable $handler): void /** * @param string $signal - * @param Consumer $consumer + * @param callable(ValuesInterface): mixed $consumer * @return void */ public function attach(string $signal, callable $consumer): void diff --git a/src/Internal/Declaration/WorkflowInstanceInterface.php b/src/Internal/Declaration/WorkflowInstanceInterface.php index 1b07f3cf..d44f735f 100644 --- a/src/Internal/Declaration/WorkflowInstanceInterface.php +++ b/src/Internal/Declaration/WorkflowInstanceInterface.php @@ -11,6 +11,8 @@ namespace Temporal\Internal\Declaration; +use Temporal\DataConverter\ValuesInterface; + interface WorkflowInstanceInterface extends InstanceInterface { /** @@ -37,8 +39,8 @@ public function addQueryHandler(string $name, callable $handler): void; public function addUpdateHandler(string $name, callable $handler): void; /** - * @param string $name - * @return \Closure + * @param non-empty-string $name + * @return \Closure(ValuesInterface): void */ public function getSignalHandler(string $name): \Closure; diff --git a/src/Internal/Marshaller/Type/ArrayType.php b/src/Internal/Marshaller/Type/ArrayType.php index 3edadda6..6128451a 100644 --- a/src/Internal/Marshaller/Type/ArrayType.php +++ b/src/Internal/Marshaller/Type/ArrayType.php @@ -69,11 +69,10 @@ public static function makeRule(\ReflectionProperty $property): ?MarshallingRule } /** - * @param array $value + * @psalm-assert array $value * @param array $current - * @return array|mixed */ - public function parse($value, $current) + public function parse($value, $current): array { if (!\is_array($value)) { throw new \InvalidArgumentException(\sprintf(self::ERROR_INVALID_TYPE, \get_debug_type($value))); diff --git a/tests/Unit/Worker/AutowiringTestCase.php b/tests/Unit/Worker/AutowiringTestCase.php index 3b20607e..83a25865 100644 --- a/tests/Unit/Worker/AutowiringTestCase.php +++ b/tests/Unit/Worker/AutowiringTestCase.php @@ -83,19 +83,4 @@ public function testInstanceCallMethodInvocation(\ReflectionFunctionAbstract $fn $this->assertSame(0xDEAD_BEEF, $handler->dispatch($this, [])); } - - #[TestDox("Checks invocation without an object context or exception otherwise (if object context required)")] - #[DataProvider('reflectionDataProvider')] - public function testStaticCallMethodInvocation(\ReflectionFunctionAbstract $fn): void - { - $handler = new AutowiredPayloads($fn, new DataConverter(new JsonConverter())); - - // If the object context is required, then the method invocation without - // "this" context should return an BadMethodCallException error. - if ($handler->isObjectContextRequired()) { - $this->expectException(\BadMethodCallException::class); - } - - $this->assertSame(0xDEAD_BEEF, $handler->dispatch(null, [])); - } } From a5fb7532b9faa6c751d0b8e2a6d87d0dd8259c55 Mon Sep 17 00:00:00 2001 From: roxblnfk Date: Thu, 23 May 2024 02:24:11 +0400 Subject: [PATCH 2/6] chore: simplify internal types and code --- .../Declaration/Dispatcher/Dispatcher.php | 10 +++---- .../Declaration/Instantiator/Instantiator.php | 19 +++---------- .../Instantiator/WorkflowInstantiator.php | 27 +++++++------------ src/Internal/Declaration/WorkflowInstance.php | 3 +-- .../WorkflowInstance/SignalQueue.php | 2 +- src/Internal/Workflow/Process/Process.php | 2 +- src/Internal/Workflow/Process/Scope.php | 1 - 7 files changed, 20 insertions(+), 44 deletions(-) diff --git a/src/Internal/Declaration/Dispatcher/Dispatcher.php b/src/Internal/Declaration/Dispatcher/Dispatcher.php index 7274e9be..353049c7 100644 --- a/src/Internal/Declaration/Dispatcher/Dispatcher.php +++ b/src/Internal/Declaration/Dispatcher/Dispatcher.php @@ -15,7 +15,7 @@ use ReflectionType; /** - * @psalm-type FunctionExecutor = \Closure(object|null, array): mixed + * @psalm-type FunctionExecutor = \Closure(object, array): mixed */ class Dispatcher implements DispatcherInterface { @@ -30,8 +30,8 @@ class Dispatcher implements DispatcherInterface public const SCOPE_STATIC = 0x02; /** + * @var \Closure(object, array): mixed * @psalm-var FunctionExecutor - * @var \Closure */ private \Closure $executor; @@ -114,13 +114,13 @@ private function scopeMatches(int $scope): bool * @psalm-return FunctionExecutor * * @param \ReflectionMethod $fun - * @return \Closure + * @return \Closure(object, array): mixed */ private function createExecutorFromMethod(\ReflectionMethod $fun): \Closure { - return static function (?object $ctx, array $arguments) use ($fun) { + return static function (object $object, array $arguments) use ($fun) { try { - return $fun->invokeArgs($ctx, $arguments); + return $fun->invokeArgs($object, $arguments); } catch (\ReflectionException $e) { throw new \BadMethodCallException($e->getMessage(), $e->getCode(), $e); } diff --git a/src/Internal/Declaration/Instantiator/Instantiator.php b/src/Internal/Declaration/Instantiator/Instantiator.php index 89b03aca..ebde7d2c 100644 --- a/src/Internal/Declaration/Instantiator/Instantiator.php +++ b/src/Internal/Declaration/Instantiator/Instantiator.php @@ -17,24 +17,11 @@ abstract class Instantiator implements InstantiatorInterface { /** * @param PrototypeInterface $prototype - * @return \ReflectionClass|null - */ - protected function getClass(PrototypeInterface $prototype): ?\ReflectionClass - { - return $prototype->getClass(); - } - - /** - * @param PrototypeInterface $prototype - * @return object|null + * @return object * @throws \ReflectionException */ - protected function getInstance(PrototypeInterface $prototype): ?object + protected function getInstance(PrototypeInterface $prototype): object { - if ($class = $this->getClass($prototype)) { - return $class->newInstance(); - } - - return null; + return $prototype->getClass()->newInstance(); } } diff --git a/src/Internal/Declaration/Instantiator/WorkflowInstantiator.php b/src/Internal/Declaration/Instantiator/WorkflowInstantiator.php index fcb56eb4..028ee115 100644 --- a/src/Internal/Declaration/Instantiator/WorkflowInstantiator.php +++ b/src/Internal/Declaration/Instantiator/WorkflowInstantiator.php @@ -12,6 +12,7 @@ namespace Temporal\Internal\Declaration\Instantiator; use Temporal\Exception\InstantiationException; +use Temporal\Interceptor\PipelineProvider; use Temporal\Interceptor\WorkflowInboundCallsInterceptor; use Temporal\Internal\Declaration\Prototype\PrototypeInterface; use Temporal\Internal\Declaration\Prototype\WorkflowPrototype; @@ -23,7 +24,7 @@ final class WorkflowInstantiator extends Instantiator { public function __construct( - private \Temporal\Interceptor\PipelineProvider $interceptorProvider, + private PipelineProvider $interceptorProvider, ) { } @@ -43,26 +44,16 @@ public function instantiate(PrototypeInterface $prototype): WorkflowInstance /** * @param PrototypeInterface $prototype - * @return object|null + * @return object * @throws \ReflectionException */ - protected function getInstance(PrototypeInterface $prototype): ?object + protected function getInstance(PrototypeInterface $prototype): object { - $handler = $prototype->getHandler(); + $handler = $prototype->getHandler() ?? throw new InstantiationException(\sprintf( + 'Unable to instantiate workflow "%s" without handler method', + $prototype->getID(), + )); - if ($handler === null) { - throw new InstantiationException(\sprintf( - 'Unable to instantiate workflow "%s" without handler method', - $prototype->getID(), - )); - } - - $class = $handler->getDeclaringClass(); - - if ($class !== null) { - return $class->newInstanceWithoutConstructor(); - } - - return null; + return $handler->getDeclaringClass()->newInstanceWithoutConstructor(); } } diff --git a/src/Internal/Declaration/WorkflowInstance.php b/src/Internal/Declaration/WorkflowInstance.php index 7c4e0bee..7e6808e6 100644 --- a/src/Internal/Declaration/WorkflowInstance.php +++ b/src/Internal/Declaration/WorkflowInstance.php @@ -17,7 +17,6 @@ use Temporal\Interceptor\WorkflowInboundCallsInterceptor; use Temporal\Internal\Declaration\Prototype\WorkflowPrototype; use Temporal\Internal\Declaration\WorkflowInstance\SignalQueue; -use Temporal\Internal\Declaration\WorkflowInstance\UpdateQueue; use Temporal\Internal\Interceptor; /** @@ -65,7 +64,7 @@ final class WorkflowInstance extends Instance implements WorkflowInstanceInterfa /** * @param WorkflowPrototype $prototype - * @param object $context + * @param object $context Workflow object * @param Interceptor\Pipeline $pipeline */ public function __construct( diff --git a/src/Internal/Declaration/WorkflowInstance/SignalQueue.php b/src/Internal/Declaration/WorkflowInstance/SignalQueue.php index b899a50a..13e3b17d 100644 --- a/src/Internal/Declaration/WorkflowInstance/SignalQueue.php +++ b/src/Internal/Declaration/WorkflowInstance/SignalQueue.php @@ -60,7 +60,7 @@ public function onSignal(callable $handler): void /** * @param string $signal - * @param callable(ValuesInterface): mixed $consumer + * @param Consumer $consumer * @return void */ public function attach(string $signal, callable $consumer): void diff --git a/src/Internal/Workflow/Process/Process.php b/src/Internal/Workflow/Process/Process.php index 588d9db2..37440778 100644 --- a/src/Internal/Workflow/Process/Process.php +++ b/src/Internal/Workflow/Process/Process.php @@ -139,7 +139,7 @@ function (SignalInput $input) use ($handler) { )->onClose( function (?\Throwable $error): void { if ($error !== null) { - // we want to fail process when signal scope fails + // Fail process when signal scope fails $this->complete($error); } } diff --git a/src/Internal/Workflow/Process/Scope.php b/src/Internal/Workflow/Process/Scope.php index bd1671f8..25961b9b 100644 --- a/src/Internal/Workflow/Process/Scope.php +++ b/src/Internal/Workflow/Process/Scope.php @@ -28,7 +28,6 @@ use Temporal\Worker\Transport\Command\RequestInterface; use Temporal\Workflow; use Temporal\Workflow\CancellationScopeInterface; -use Temporal\Workflow\WorkflowContextInterface; /** * Unlike Java implementation, PHP has merged coroutine and cancellation scope into a single instance. From 2203f7b5c1f1ac05c73d305c991d0a0520a20d8a Mon Sep 17 00:00:00 2001 From: roxblnfk Date: Thu, 23 May 2024 02:26:26 +0400 Subject: [PATCH 3/6] fix: fixed a Workflow hang in cases where a non-promise was yielded --- src/Internal/Workflow/Process/Scope.php | 2 ++ .../src/Workflow/YieldScalarsWorkflow.php | 30 +++++++++++++++++++ tests/Functional/SimpleWorkflowTestCase.php | 8 +++++ 3 files changed, 40 insertions(+) create mode 100644 tests/Fixtures/src/Workflow/YieldScalarsWorkflow.php diff --git a/src/Internal/Workflow/Process/Scope.php b/src/Internal/Workflow/Process/Scope.php index 25961b9b..a9671b5b 100644 --- a/src/Internal/Workflow/Process/Scope.php +++ b/src/Internal/Workflow/Process/Scope.php @@ -446,6 +446,7 @@ protected function makeCurrent(): void protected function next(): void { $this->makeCurrent(); + begin: $this->context->resolveConditions(); if (!$this->coroutine->valid()) { @@ -481,6 +482,7 @@ protected function next(): void default: $this->coroutine->send($current); + goto begin; } } diff --git a/tests/Fixtures/src/Workflow/YieldScalarsWorkflow.php b/tests/Fixtures/src/Workflow/YieldScalarsWorkflow.php new file mode 100644 index 00000000..a5eec719 --- /dev/null +++ b/tests/Fixtures/src/Workflow/YieldScalarsWorkflow.php @@ -0,0 +1,30 @@ +fail('LocalActivity not found in history'); } + public function testYieldNonPromises(): void + { + $workflow = $this->workflowClient->newWorkflowStub(YieldScalarsWorkflow::class); + $run = $this->workflowClient->start($workflow, ['hello', 'world', '!']); + $this->assertSame([ 'hello', 'world', '!'], $run->getResult('array')); + } + private function assertContainsEvent(WorkflowExecution $execution, int $event): void { $history = $this->workflowClient->getWorkflowHistory( From 3112e73d6be38ad90779ecfa6b7d6f1ff9930201 Mon Sep 17 00:00:00 2001 From: roxblnfk Date: Thu, 23 May 2024 02:59:54 +0400 Subject: [PATCH 4/6] chore: simplify code, correct types --- src/Internal/Declaration/WorkflowInstance.php | 7 ++++--- src/Internal/Declaration/WorkflowInstanceInterface.php | 4 +++- src/Internal/Transport/Router/InvokeUpdate.php | 8 ++++---- src/Internal/Workflow/ProcessCollection.php | 6 ------ 4 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/Internal/Declaration/WorkflowInstance.php b/src/Internal/Declaration/WorkflowInstance.php index 7e6808e6..d4793e6b 100644 --- a/src/Internal/Declaration/WorkflowInstance.php +++ b/src/Internal/Declaration/WorkflowInstance.php @@ -11,6 +11,7 @@ namespace Temporal\Internal\Declaration; +use React\Promise\PromiseInterface; use Temporal\DataConverter\ValuesInterface; use Temporal\Interceptor\WorkflowInbound\QueryInput; use Temporal\Interceptor\WorkflowInbound\UpdateInput; @@ -22,10 +23,10 @@ /** * @psalm-import-type DispatchableHandler from InstanceInterface * @psalm-type QueryHandler = \Closure(QueryInput): mixed - * @psalm-type UpdateHandler = \Closure(UpdateInput): mixed + * @psalm-type UpdateHandler = \Closure(UpdateInput): PromiseInterface * @psalm-type ValidateUpdateHandler = \Closure(UpdateInput): void * @psalm-type QueryExecutor = \Closure(QueryInput, callable(ValuesInterface): mixed): mixed - * @psalm-type UpdateExecutor = \Closure(UpdateInput, callable(ValuesInterface): mixed): mixed + * @psalm-type UpdateExecutor = \Closure(UpdateInput, callable(ValuesInterface): mixed): PromiseInterface * @psalm-type ValidateUpdateExecutor = \Closure(UpdateInput, callable(ValuesInterface): mixed): mixed * @psalm-type UpdateValidator = \Closure(UpdateInput, UpdateHandler): void */ @@ -166,7 +167,7 @@ public function findQueryHandler(string $name): ?\Closure /** * @param string $name - * @return \Closure + * @return UpdateHandler|null */ public function findUpdateHandler(string $name): ?\Closure { diff --git a/src/Internal/Declaration/WorkflowInstanceInterface.php b/src/Internal/Declaration/WorkflowInstanceInterface.php index d44f735f..8845ad76 100644 --- a/src/Internal/Declaration/WorkflowInstanceInterface.php +++ b/src/Internal/Declaration/WorkflowInstanceInterface.php @@ -11,7 +11,9 @@ namespace Temporal\Internal\Declaration; +use React\Promise\PromiseInterface; use Temporal\DataConverter\ValuesInterface; +use Temporal\Interceptor\WorkflowInbound\UpdateInput; interface WorkflowInstanceInterface extends InstanceInterface { @@ -46,7 +48,7 @@ public function getSignalHandler(string $name): \Closure; /** * @param non-empty-string $name - * @return \Closure + * @return null|\Closure(UpdateInput): PromiseInterface */ public function findUpdateHandler(string $name): ?\Closure; diff --git a/src/Internal/Transport/Router/InvokeUpdate.php b/src/Internal/Transport/Router/InvokeUpdate.php index f73d8459..a91ef480 100644 --- a/src/Internal/Transport/Router/InvokeUpdate.php +++ b/src/Internal/Transport/Router/InvokeUpdate.php @@ -86,12 +86,11 @@ public function handle(ServerRequestInterface $request, array $headers, Deferred return; } - // There validation is passed + // Validation has passed - /** @var PromiseInterface $promise */ $promise = $handler($input); $promise->then( - static function (mixed $value) use ($updateId, $context, $resolver): void { + static function (mixed $value) use ($updateId, $context): void { $context->getClient()->send(new UpdateResponse( command: UpdateResponse::COMMAND_COMPLETED, values: EncodedValues::fromValues([$value]), @@ -99,7 +98,7 @@ static function (mixed $value) use ($updateId, $context, $resolver): void { updateId: $updateId, )); }, - static function (\Throwable $err) use ($updateId, $context, $resolver): void { + static function (\Throwable $err) use ($updateId, $context): void { $context->getClient()->send(new UpdateResponse( command: UpdateResponse::COMMAND_COMPLETED, values: null, @@ -112,6 +111,7 @@ static function (\Throwable $err) use ($updateId, $context, $resolver): void { /** * @param non-empty-string $name + * @return \Closure(UpdateInput): PromiseInterface */ private function getUpdateHandler(WorkflowInstanceInterface $instance, string $name): \Closure { diff --git a/src/Internal/Workflow/ProcessCollection.php b/src/Internal/Workflow/ProcessCollection.php index 4006a932..344ab782 100644 --- a/src/Internal/Workflow/ProcessCollection.php +++ b/src/Internal/Workflow/ProcessCollection.php @@ -12,7 +12,6 @@ namespace Temporal\Internal\Workflow; use Temporal\Internal\Repository\ArrayRepository; -use Temporal\Internal\Transport\ClientInterface; use Temporal\Internal\Workflow\Process\Process; /** @@ -22,11 +21,6 @@ class ProcessCollection extends ArrayRepository { private const ERROR_PROCESS_NOT_FOUND = 'Process #%s not found.'; - public function __construct() - { - parent::__construct(); - } - /** * @param string $runId * @param non-empty-string|null $error Error message if the process was not found. From 293a0d523dcb1f2ad3503c7d6aa85fdcde947257 Mon Sep 17 00:00:00 2001 From: roxblnfk Date: Mon, 27 May 2024 13:16:14 +0400 Subject: [PATCH 5/6] chore: fix types --- src/Internal/Declaration/WorkflowInstance.php | 11 +++++++--- .../Declaration/WorkflowInstanceInterface.php | 5 +++-- src/Internal/Transport/Router/InvokeQuery.php | 21 +++++++++---------- .../Transport/Router/InvokeUpdate.php | 1 + 4 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/Internal/Declaration/WorkflowInstance.php b/src/Internal/Declaration/WorkflowInstance.php index d4793e6b..5cc99271 100644 --- a/src/Internal/Declaration/WorkflowInstance.php +++ b/src/Internal/Declaration/WorkflowInstance.php @@ -156,8 +156,8 @@ public function getSignalQueue(): SignalQueue /** * @param non-empty-string $name - * @return null|\Closure(ValuesInterface):mixed * + * @return null|\Closure(QueryInput): mixed * @psalm-return QueryHandler|null */ public function findQueryHandler(string $name): ?\Closure @@ -166,8 +166,10 @@ public function findQueryHandler(string $name): ?\Closure } /** - * @param string $name - * @return UpdateHandler|null + * @param non-empty-string $name + * + * @return null|\Closure(UpdateInput): PromiseInterface + * @psalm-return UpdateHandler|null */ public function findUpdateHandler(string $name): ?\Closure { @@ -176,6 +178,9 @@ public function findUpdateHandler(string $name): ?\Closure /** * @param non-empty-string $name + * + * @return null|\Closure(UpdateInput): void + * @psalm-return ValidateUpdateHandler|null */ public function findValidateUpdateHandler(string $name): ?\Closure { diff --git a/src/Internal/Declaration/WorkflowInstanceInterface.php b/src/Internal/Declaration/WorkflowInstanceInterface.php index 8845ad76..1c9862f8 100644 --- a/src/Internal/Declaration/WorkflowInstanceInterface.php +++ b/src/Internal/Declaration/WorkflowInstanceInterface.php @@ -13,6 +13,7 @@ use React\Promise\PromiseInterface; use Temporal\DataConverter\ValuesInterface; +use Temporal\Interceptor\WorkflowInbound\QueryInput; use Temporal\Interceptor\WorkflowInbound\UpdateInput; interface WorkflowInstanceInterface extends InstanceInterface @@ -23,8 +24,8 @@ interface WorkflowInstanceInterface extends InstanceInterface public function initConstructor(): void; /** - * @param string $name - * @return \Closure|null + * @param non-empty-string $name + * @return null|\Closure(QueryInput): mixed */ public function findQueryHandler(string $name): ?\Closure; diff --git a/src/Internal/Transport/Router/InvokeQuery.php b/src/Internal/Transport/Router/InvokeQuery.php index 4036ddda..9ce45a1a 100644 --- a/src/Internal/Transport/Router/InvokeQuery.php +++ b/src/Internal/Transport/Router/InvokeQuery.php @@ -52,6 +52,7 @@ public function __construct( */ public function handle(ServerRequestInterface $request, array $headers, Deferred $resolver): void { + /** @var non-empty-string $name */ $name = $request->getOptions()['name']; $process = $this->findProcessOrFail($request->getID()); $context = $process->getContext(); @@ -79,19 +80,17 @@ static function () use ($name, $request, $resolver, $handler, $context): void { /** * @param WorkflowInstanceInterface $instance - * @param string $name - * @return \Closure + * @param non-empty-string $name + * @return \Closure(QueryInput): mixed */ private function findQueryHandlerOrFail(WorkflowInstanceInterface $instance, string $name): \Closure { - $handler = $instance->findQueryHandler($name); - - if ($handler === null) { - $available = \implode(' ', $instance->getQueryHandlerNames()); - - throw new \LogicException(\sprintf(self::ERROR_QUERY_NOT_FOUND, $name, $available)); - } - - return $handler; + return $instance->findQueryHandler($name) ?? throw new \LogicException( + \sprintf( + self::ERROR_QUERY_NOT_FOUND, + $name, + \implode(' ', $instance->getQueryHandlerNames()) + ), + ); } } diff --git a/src/Internal/Transport/Router/InvokeUpdate.php b/src/Internal/Transport/Router/InvokeUpdate.php index a91ef480..60858c76 100644 --- a/src/Internal/Transport/Router/InvokeUpdate.php +++ b/src/Internal/Transport/Router/InvokeUpdate.php @@ -36,6 +36,7 @@ public function handle(ServerRequestInterface $request, array $headers, Deferred try { $instance = $process->getWorkflowInstance(); + /** @var non-empty-string $name */ $name = $request->getOptions()['name']; $handler = $this->getUpdateHandler($instance, $name); /** @psalm-suppress InaccessibleProperty */ From 49c3f5210693b2a92e1bc0a073a075075fd11e26 Mon Sep 17 00:00:00 2001 From: roxblnfk Date: Mon, 27 May 2024 18:36:30 +0400 Subject: [PATCH 6/6] chore: fix psalm issues --- psalm-baseline.xml | 20 ------------------- .../Declaration/Dispatcher/Dispatcher.php | 8 ++------ src/Internal/Marshaller/Type/ArrayType.php | 1 + 3 files changed, 3 insertions(+), 26 deletions(-) diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 045712fb..e6ccb4cd 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -509,9 +509,6 @@ - - getInstance($prototype)]]> - @@ -527,12 +524,6 @@ - - getInstance($prototype)]]> - - - - @@ -595,12 +586,10 @@ - - @@ -615,7 +604,6 @@ - @@ -752,13 +740,9 @@ - - - - @@ -1144,10 +1128,6 @@ - - - - diff --git a/src/Internal/Declaration/Dispatcher/Dispatcher.php b/src/Internal/Declaration/Dispatcher/Dispatcher.php index 353049c7..2db1af61 100644 --- a/src/Internal/Declaration/Dispatcher/Dispatcher.php +++ b/src/Internal/Declaration/Dispatcher/Dispatcher.php @@ -131,15 +131,11 @@ private function createExecutorFromMethod(\ReflectionMethod $fun): \Closure * @psalm-return FunctionExecutor * * @param \ReflectionFunction $fun - * @return \Closure + * @return \Closure(object, array): mixed */ private function createExecutorFromFunction(\ReflectionFunction $fun): \Closure { - return static function (?object $ctx, array $arguments) use ($fun) { - if ($ctx === null) { - return $fun->invoke(...$arguments); - } - + return static function (object $ctx, array $arguments) use ($fun) { $closure = $fun->getClosure(); try { diff --git a/src/Internal/Marshaller/Type/ArrayType.php b/src/Internal/Marshaller/Type/ArrayType.php index 6128451a..271331a4 100644 --- a/src/Internal/Marshaller/Type/ArrayType.php +++ b/src/Internal/Marshaller/Type/ArrayType.php @@ -70,6 +70,7 @@ public static function makeRule(\ReflectionProperty $property): ?MarshallingRule /** * @psalm-assert array $value + * @param mixed $value * @param array $current */ public function parse($value, $current): array