Skip to content

Commit

Permalink
Merge pull request #85 from spiral/add-registry
Browse files Browse the repository at this point in the history
Add Workflow and Activity registry
  • Loading branch information
butschster committed May 20, 2024
2 parents df2d14e + f9d1d5b commit 6a2fa0e
Show file tree
Hide file tree
Showing 11 changed files with 115 additions and 10 deletions.
6 changes: 6 additions & 0 deletions psalm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@
</ignoreFiles>
</projectFiles>
<issueHandlers>
<DeprecatedInterface>
<errorLevel type="suppress">
<file name="src/Commands/InfoCommand.php"/>
<file name="src/DeclarationLocator.php"/>
</errorLevel>
</DeprecatedInterface>
<PropertyNotSetInConstructor>
<errorLevel type="suppress">
<file name="src/Commands/Scaffolder/ActivityCommand.php"/>
Expand Down
4 changes: 3 additions & 1 deletion src/Bootloader/TemporalBridgeBootloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use Spiral\TemporalBridge\Config\TemporalConfig;
use Spiral\TemporalBridge\DeclarationLocator;
use Spiral\TemporalBridge\DeclarationLocatorInterface;
use Spiral\TemporalBridge\DeclarationRegistryInterface;
use Spiral\TemporalBridge\Dispatcher;
use Spiral\TemporalBridge\WorkerFactory;
use Spiral\TemporalBridge\WorkerFactoryInterface;
Expand Down Expand Up @@ -63,8 +64,9 @@ public function defineSingletons(): array
rpc: Goridge::create(),
),
WorkerFactoryInterface::class => WorkerFactory::class,
DeclarationLocatorInterface::class => DeclarationRegistryInterface::class,

DeclarationLocatorInterface::class => static fn() => new DeclarationLocator(
DeclarationRegistryInterface::class => static fn() => new DeclarationLocator(
reader: new AttributeReader(),
),

Expand Down
1 change: 1 addition & 0 deletions src/Config/TemporalConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
*/
final class TemporalConfig extends InjectableConfig
{
/** @var non-empty-string */
public const CONFIG = 'temporal';

protected array $config = [
Expand Down
7 changes: 6 additions & 1 deletion src/DeclarationLocator.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#[Singleton]
#[TargetAttribute(WorkflowInterface::class)]
#[TargetAttribute(ActivityInterface::class)]
final class DeclarationLocator implements DeclarationLocatorInterface, TokenizationListenerInterface
final class DeclarationLocator implements DeclarationRegistryInterface, TokenizationListenerInterface
{
private array $declarations = [];

Expand All @@ -23,6 +23,11 @@ public function __construct(
) {
}

public function addDeclaration(\ReflectionClass|string $class): void
{
$this->listen($class instanceof \ReflectionClass ? $class : new \ReflectionClass($class));
}

public function getDeclarations(): iterable
{
foreach ($this->declarations as $type => $classes) {
Expand Down
3 changes: 3 additions & 0 deletions src/DeclarationLocatorInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
use Temporal\Activity\ActivityInterface;
use Temporal\Workflow\WorkflowInterface;

/**
* @deprecated Use {@see DeclarationRegistryInterface} instead.
*/
interface DeclarationLocatorInterface
{
/**
Expand Down
15 changes: 15 additions & 0 deletions src/DeclarationRegistryInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace Spiral\TemporalBridge;

interface DeclarationRegistryInterface extends DeclarationLocatorInterface
{
/**
* Add a new declaration to the registry.
*
* @param \ReflectionClass|class-string $class Workflow or activity class name or reflection.
*/
public function addDeclaration(\ReflectionClass|string $class): void;
}
2 changes: 1 addition & 1 deletion src/Dispatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public function serve(): void
/**
* @var array<class-string<WorkflowInterface>|class-string<ActivityInterface>, ReflectionClass> $declarations
*/
$declarations = $this->container->get(DeclarationLocatorInterface::class)->getDeclarations();
$declarations = $this->container->get(DeclarationRegistryInterface::class)->getDeclarations();

// factory initiates and runs task queue specific activity and workflow workers
/** @var WorkerFactoryInterface $factory */
Expand Down
3 changes: 2 additions & 1 deletion src/Scaffolder/Declaration/ActivityDeclaration.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@

final class ActivityDeclaration extends AbstractDeclaration
{
/** @var non-empty-string */
public const TYPE = 'activity';

public function __construct(
ScaffolderConfig $config,
string $name,
?string $comment = null,
?string $namespace = null,
private ?string $activityName = null,
private readonly ?string $activityName = null,
) {
parent::__construct($config, $name, $comment, $namespace);
}
Expand Down
1 change: 1 addition & 0 deletions src/Scaffolder/Declaration/WorkflowDeclaration.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

final class WorkflowDeclaration extends AbstractDeclaration
{
/** @var non-empty-string */
public const TYPE = 'workflow';

public function __construct(
Expand Down
77 changes: 74 additions & 3 deletions tests/src/DeclarationLocatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,14 @@

namespace Spiral\TemporalBridge\Tests;

use Mockery as m;
use Spiral\Attributes\AttributeReader;
use Spiral\TemporalBridge\DeclarationLocator;
use Spiral\Tokenizer\ClassesInterface;
use Temporal\Activity\ActivityInterface;
use Temporal\Workflow\WorkflowInterface;

final class DeclarationLocatorTest extends TestCase
{
private DeclarationLocator $locator;
private m\LegacyMockInterface|m\MockInterface $classes;

protected function setUp(): void
{
Expand Down Expand Up @@ -68,6 +65,80 @@ public function testWorkflowsShouldBeRegistered(): void
$this->assertSame(ActivityInterface::class, $result[3][0]);
$this->assertSame($activity2, $result[3][1]);
}

public function testAddDeclarationSkipsNonClasses(): void
{
$this->locator->addDeclaration(TestEnum::class);
$this->locator->addDeclaration(TestAbstractClass::class);
$this->locator->addDeclaration(TestInterface::class);
$this->locator->addDeclaration(new \ReflectionClass(TestEnum::class));
$this->locator->addDeclaration(new \ReflectionClass(TestAbstractClass::class));
$this->locator->addDeclaration(new \ReflectionClass(TestInterface::class));

$result = [];

foreach ($this->locator->getDeclarations() as $type => $class) {
$result[] = [$type, $class];
}

$this->assertCount(0, $result);
}

public function testAddDeclarationReflections(): void
{
$this->locator->addDeclaration($workflow1 = new \ReflectionClass(TestWorkflowClass::class));
$this->locator->addDeclaration($workflow2 = new \ReflectionClass(TestWorkflowClassWithInterface::class));
$this->locator->addDeclaration($activity1 = new \ReflectionClass(TestActivityClass::class));
$this->locator->addDeclaration($activity2 = new \ReflectionClass(TestActivityClassWithInterface::class));

$result = [];

foreach ($this->locator->getDeclarations() as $type => $class) {
$result[] = [$type, $class];
}

$this->assertCount(4, $result);

$this->assertSame(WorkflowInterface::class, $result[0][0]);
$this->assertSame($workflow1, $result[0][1]);

$this->assertSame(WorkflowInterface::class, $result[1][0]);
$this->assertSame($workflow2, $result[1][1]);

$this->assertSame(ActivityInterface::class, $result[2][0]);
$this->assertSame($activity1, $result[2][1]);

$this->assertSame(ActivityInterface::class, $result[3][0]);
$this->assertSame($activity2, $result[3][1]);
}

public function testAddDeclarationClassNames(): void
{
$this->locator->addDeclaration(TestWorkflowClass::class);
$this->locator->addDeclaration(TestWorkflowClassWithInterface::class);
$this->locator->addDeclaration(TestActivityClass::class);
$this->locator->addDeclaration(TestActivityClassWithInterface::class);

$result = [];

foreach ($this->locator->getDeclarations() as $type => $class) {
$result[] = [$type, $class];
}

$this->assertCount(4, $result);

$this->assertSame(WorkflowInterface::class, $result[0][0]);
$this->assertSame(TestWorkflowClass::class, $result[0][1]->getName());

$this->assertSame(WorkflowInterface::class, $result[1][0]);
$this->assertSame(TestWorkflowClassWithInterface::class, $result[1][1]->getName());

$this->assertSame(ActivityInterface::class, $result[2][0]);
$this->assertSame(TestActivityClass::class, $result[2][1]->getName());

$this->assertSame(ActivityInterface::class, $result[3][0]);
$this->assertSame(TestActivityClassWithInterface::class, $result[3][1]->getName());
}
}

enum TestEnum
Expand Down
6 changes: 3 additions & 3 deletions tests/src/DispatcherTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
use Spiral\Attributes\AttributeReader;
use Spiral\RoadRunnerBridge\RoadRunnerMode;
use Spiral\TemporalBridge\Config\TemporalConfig;
use Spiral\TemporalBridge\DeclarationLocatorInterface;
use Spiral\TemporalBridge\DeclarationRegistryInterface;
use Spiral\TemporalBridge\DeclarationWorkerResolver;
use Spiral\TemporalBridge\Dispatcher;
use Spiral\TemporalBridge\Tests\App\SomeActivity;
Expand Down Expand Up @@ -41,7 +41,7 @@ protected function setUp(): void

public function testServeWithoutDeclarations(): void
{
$locator = $this->mockContainer(DeclarationLocatorInterface::class);
$locator = $this->mockContainer(DeclarationRegistryInterface::class);
$locator->shouldReceive('getDeclarations')->once()->andReturn([]);

$registry = $this->mockContainer(WorkersRegistryInterface::class);
Expand All @@ -59,7 +59,7 @@ public function testServeWithoutDeclarations(): void

public function testServeWithDeclarations(): void
{
$locator = $this->mockContainer(DeclarationLocatorInterface::class);
$locator = $this->mockContainer(DeclarationRegistryInterface::class);
$locator->shouldReceive('getDeclarations')->once()->andReturnUsing(function () {
yield WorkflowInterface::class => new \ReflectionClass(SomeWorkflow::class);
yield WorkflowInterface::class => new \ReflectionClass(SomeWorkflowWithMultipleWorkers::class);
Expand Down

0 comments on commit 6a2fa0e

Please sign in to comment.