Skip to content

Commit

Permalink
Merge branch 'master' into meta-storm-plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
roxblnfk authored Jan 17, 2025
2 parents 06469d8 + fc67190 commit ff03e78
Show file tree
Hide file tree
Showing 19 changed files with 217 additions and 53 deletions.
1 change: 1 addition & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
>
<testsuites>
<testsuite name="Acceptance">
<directory suffix="Test.php">tests/Acceptance/Extra</directory>
<directory suffix="Test.php">tests/Acceptance/Harness</directory>
</testsuite>
<testsuite name="Arch">
Expand Down
12 changes: 11 additions & 1 deletion psalm-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,23 @@
<code><![CDATA[$workflowType]]></code>
</PropertyNotSetInConstructor>
</file>
<file src="src/Client/Schedule/ScheduleOptions.php">
<DeprecatedProperty>
<code><![CDATA[$this->namespace]]></code>
</DeprecatedProperty>
</file>
<file src="src/Client/Schedule/Spec/ScheduleSpec.php">
<DeprecatedProperty>
<code><![CDATA[$this->excludeCalendarList]]></code>
<code><![CDATA[$this->excludeCalendarList]]></code>
</DeprecatedProperty>
</file>
<file src="src/Client/ScheduleClient.php">
<DeprecatedProperty>
<code><![CDATA[$options->namespace]]></code>
<code><![CDATA[$options->namespace]]></code>
</DeprecatedProperty>
</file>
<file src="src/Client/Update/UpdateHandle.php">
<PossiblyNullArgument>
<code><![CDATA[$result->getSuccess()]]></code>
Expand Down Expand Up @@ -428,7 +439,6 @@
<code><![CDATA[$attr->getFailure()]]></code>
<code><![CDATA[$attr->getResult()]]></code>
<code><![CDATA[$input->workflowType]]></code>
<code><![CDATA[$input->workflowType]]></code>
<code><![CDATA[$result->getQueryResult()]]></code>
<code><![CDATA[$this->execution]]></code>
<code><![CDATA[$this->execution]]></code>
Expand Down
13 changes: 10 additions & 3 deletions src/Client/Schedule/ScheduleOptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,23 @@ final class ScheduleOptions
{
use CloneWith;

public readonly string $namespace;
public readonly bool $triggerImmediately;
/**
* @deprecated will be removed in the next major version.
*/
public readonly ?string $namespace;

/**
* @var list<BackfillPeriod>
*/
public readonly array $backfills;

public readonly bool $triggerImmediately;
public readonly EncodedCollection $memo;
public readonly EncodedCollection $searchAttributes;

private function __construct()
{
$this->namespace = 'default';
$this->namespace = null;
$this->triggerImmediately = false;
$this->backfills = [];
$this->memo = EncodedCollection::empty();
Expand All @@ -41,6 +44,10 @@ public static function new(): self
return new self();
}

/**
* @deprecated Configure the namespace on the {@see \Temporal\Client\ClientOptions} instead
* when creating the {@see \Temporal\Client\ScheduleClient}.
*/
public function withNamespace(string $namespace): self
{
/** @see self::$namespace */
Expand Down
4 changes: 2 additions & 2 deletions src/Client/ScheduleClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public function createSchedule(
$request = new CreateScheduleRequest();
$request
->setRequestId(Uuid::v4())
->setNamespace($options->namespace)
->setNamespace($options->namespace ?? $this->clientOptions->namespace)
->setScheduleId($scheduleId)
->setIdentity($this->clientOptions->identity);

Expand Down Expand Up @@ -123,7 +123,7 @@ public function createSchedule(
$this->converter,
$this->marshaller,
$this->protoConverter,
$options->namespace,
$options->namespace ?? $this->clientOptions->namespace,
$scheduleId,
);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Internal/Client/ResponseToResultMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public function __construct(
public function mapUpdateWorkflowResponse(
UpdateWorkflowExecutionResponse $result,
string $updateName,
string $workflowType,
?string $workflowType,
WorkflowExecution $workflowExecution,
): StartUpdateOutput {
$outcome = $result->getOutcome();
Expand Down
5 changes: 4 additions & 1 deletion src/Internal/Declaration/Dispatcher/Dispatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,10 @@ private function createExecutorFromFunction(\ReflectionFunction $fun): \Closure
throw new \BadMethodCallException($message, $type, $error);
});

return $closure->call($ctx, ...$arguments);

return $fun->isStatic()
? $closure->bindTo(null, $ctx::class)?->__invoke(...$arguments) ?? $closure(...$arguments)
: $closure->call($ctx, ...$arguments);
} finally {
\restore_error_handler();
}
Expand Down
9 changes: 5 additions & 4 deletions src/Internal/Workflow/Process/DeferredGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public function send(mixed $value): mixed
*/
public function getReturn(): mixed
{
// $this->start();
$this->finished or throw new \LogicException('Cannot get return value of a generator that was not finished.');
try {
return $this->generator->getReturn();
} catch (\Throwable $e) {
Expand Down Expand Up @@ -149,7 +149,8 @@ public function valid(): bool
{
$this->start();
try {
return $this->generator->valid();
$result = $this->generator->valid() or $this->finished = true;
return $result;
} catch (\Throwable $e) {
$this->handleException($e);
}
Expand Down Expand Up @@ -218,9 +219,9 @@ private function handleException(\Throwable $e): never
{
$this->finished and throw $e;
$this->finished = true;
foreach ($this->catchers as $catch) {
foreach ($this->catchers as $catcher) {
try {
$catch($e);
$catcher($e);
} catch (\Throwable) {
// Do nothing.
}
Expand Down
19 changes: 8 additions & 11 deletions src/Internal/Workflow/Process/Scope.php
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,8 @@ public function startSignal(callable $handler, ValuesInterface $values, string $
*/
public function attach(\Generator $generator): self
{
$this->coroutine = DeferredGenerator::fromGenerator($generator);
$this->coroutine = DeferredGenerator::fromGenerator($generator)
->catch($this->onException(...));

$this->next();
return $this;
Expand Down Expand Up @@ -386,13 +387,13 @@ protected function next(): void
begin:
$this->context->resolveConditions();

if (!$this->coroutine->valid()) {
try {
try {
if (!$this->coroutine->valid()) {
$this->onResult($this->coroutine->getReturn());
} catch (\Throwable) {
$this->onResult(null);
return;
}

} catch (\Throwable) {
$this->onResult(null);
return;
}

Expand All @@ -418,11 +419,7 @@ protected function next(): void
break;

case $current instanceof \Generator:
try {
$this->nextPromise($this->createScope(false)->attach($current));
} catch (\Throwable $e) {
$this->coroutine->throw($e);
}
$this->nextPromise($this->createScope(false)->attach($current));
break;

default:
Expand Down
4 changes: 4 additions & 0 deletions src/Workflow.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use Temporal\Client\WorkflowStubInterface;
use Temporal\DataConverter\Type;
use Temporal\DataConverter\ValuesInterface;
use Temporal\Exception\Failure\CanceledFailure;
use Temporal\Exception\OutOfContextException;
use Temporal\Internal\Support\Facade;
use Temporal\Internal\Workflow\ScopeContext;
Expand Down Expand Up @@ -958,6 +959,9 @@ public static function uuid7(?\DateTimeInterface $dateTime = null): PromiseInter
* Run a function when the mutex is released.
* The mutex is locked for the duration of the function.
*
* Note that calling the method creates a non-detached asynchronous context {@see Workflow::async()}.
* Closing the context using the `cancel()` method will reject the returned promise with a {@see CanceledFailure}.
*
* @template T
* @param Mutex $mutex Mutex name or instance.
* @param callable(): T $callable Function to run.
Expand Down
11 changes: 11 additions & 0 deletions tests/Acceptance/Extra/Schedule/ScheduleClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,17 @@ public function listSchedulesWithQuery(
);
}

// Wait for schedules to be created
$deadline = \microtime(true) + 5;
check:
$paginator = $client->listSchedules(
pageSize: 10,
query: 'bar = 4242'
);
if (\count($paginator->getPageItems()) < 6 && \microtime(true) < $deadline) {
goto check;
}

try {
$paginator = $client->listSchedules(
pageSize: 5,
Expand Down
23 changes: 20 additions & 3 deletions tests/Acceptance/Extra/Update/UntypedStubTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
use Temporal\Client\WorkflowClientInterface;
use Temporal\Client\WorkflowStubInterface;
use Temporal\Exception\Client\TimeoutException;
use Temporal\Exception\Client\UntypedStubException;
use Temporal\Exception\Client\WorkflowUpdateException;
use Temporal\Internal\Support\DateInterval;
use Temporal\Tests\Acceptance\App\Attribute\Stub;
use Temporal\Tests\Acceptance\App\TestCase;
Expand Down Expand Up @@ -37,7 +37,11 @@ public function fetchResolvedResultAfterWorkflowCompleted(

$this->assertSame(['key' => 'resolved'], (array)$result, 'Workflow result contains resolved value');
$this->assertFalse($handle->hasResult());
$this->assertFalse($resolver->hasResult(), 'Resolver should not have result because of wait policy');

// Since Temporal CLI 1.2.0, the result is available immediately after the operation
$this->assertTrue($resolver->hasResult());
$this->assertSame('resolved', $resolver->getResult());

// Fetch result
$this->assertSame('resolved', $handle->getResult());
$this->assertTrue($handle->hasResult());
Expand Down Expand Up @@ -68,14 +72,27 @@ public function fetchResultWithTimeout(
$this->assertSame(['key' => null], (array)$result, 'Workflow result contains resolved value');
}

#[Test]
public function useClientRunningWorkflowStub(
#[Stub('Extra_Update_UntypedStub')] WorkflowStubInterface $stub,
WorkflowClientInterface $client,
): void {
$untyped = $client->newUntypedRunningWorkflowStub(
$stub->getExecution()->getID(),
$stub->getExecution()->getRunID(),
);

$this->fetchResolvedResultAfterWorkflowCompleted($untyped);
}

#[Test]
public function handleUnknownUpdate(
#[Stub('Extra_Update_UntypedStub')] WorkflowStubInterface $stub,
): void {
try {
$stub->startUpdate('unknownUpdateMethod', '42');
$this->fail('Should throw exception');
} catch (UntypedStubException $e) {
} catch (WorkflowUpdateException $e) {
$this->assertStringContainsString(
'unknown update method unknownUpdateMethod',
$e->getPrevious()->getMessage(),
Expand Down
2 changes: 1 addition & 1 deletion tests/Acceptance/Extra/Update/UpdateWithStartTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public function failWithBadUpdateName(
try {
$stub->getResult(timeout: 1);
$this->fail('Workflow must fail');
} catch (WorkflowFailedException $e) {
} catch (WorkflowFailedException) {
$this->assertTrue(true);
}
}
Expand Down
6 changes: 5 additions & 1 deletion tests/Acceptance/Extra/Workflow/AllHandlersFinishedTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ public function updateHandlersWithOneCall(

$this->assertSame(['key' => 'resolved'], (array) $result, 'Workflow result contains resolved value');
$this->assertFalse($handle->hasResult());
$this->assertFalse($resolver->hasResult(), 'Resolver should not have result because of wait policy');

// Since Temporal CLI 1.2.0, the result is available immediately after the operation
$this->assertTrue($resolver->hasResult());
$this->assertSame('resolved', $resolver->getResult());

// Fetch signal's result
$this->assertSame('resolved', $handle->getResult());
$this->assertTrue($handle->hasResult());
Expand Down
12 changes: 10 additions & 2 deletions tests/Acceptance/Extra/Workflow/MutexRunLockedTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use React\Promise\PromiseInterface;
use Temporal\Client\WorkflowStubInterface;
use Temporal\DataConverter\Type;
use Temporal\Exception\Failure\CanceledFailure;
use Temporal\Tests\Acceptance\App\Attribute\Stub;
use Temporal\Tests\Acceptance\App\TestCase;
use Temporal\Workflow;
Expand All @@ -28,6 +29,7 @@ public function runLockedWithGeneratorAndAwait(
$this->assertTrue($result[0], 'Mutex must be unlocked after runLocked is finished');
$this->assertTrue($result[1], 'The function inside runLocked mist wait for signal');
$this->assertTrue($result[2], 'Mutex must be locked during runLocked');
$this->assertNull($result[3], 'No exception must be thrown');
}

#[Test]
Expand All @@ -41,6 +43,7 @@ public function runLockedAndCancel(

$this->assertTrue($result[0], 'Mutex must be unlocked after runLocked is cancelled');
$this->assertNull($result[2], 'Mutex must be locked during runLocked');
$this->assertSame(CanceledFailure::class, $result[3], 'CanceledFailure must be thrown');
}
}

Expand All @@ -64,7 +67,12 @@ public function __construct()
#[Workflow\ReturnType(Type::TYPE_ARRAY)]
public function handle(): \Generator
{
$result = yield $this->promise = Workflow::runLocked($this->mutex, $this->runLocked(...));
$exception = null;
try {
$result = yield $this->promise = Workflow::runLocked($this->mutex, $this->runLocked(...));
} catch (\Throwable $e) {
$exception = $e::class;
}

$trailed = false;
yield Workflow::await(
Expand All @@ -78,7 +86,7 @@ public function handle(): \Generator
// that was created inside the first runLocked
$trailed and throw new \Exception('The trailed runLocked must not be executed.');

return [$this->unlocked, $this->unblock, $result];
return [$this->unlocked, $this->unblock, $result, $exception];
}

#[Workflow\SignalMethod]
Expand Down
Loading

0 comments on commit ff03e78

Please sign in to comment.