Skip to content

Commit

Permalink
Merge pull request #78 from spiral/feature/scheduler-client
Browse files Browse the repository at this point in the history
Adds Temporal Schedule API support
  • Loading branch information
butschster authored Dec 25, 2023
2 parents 4407049 + 4164b44 commit 4e2f44f
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 10 deletions.
33 changes: 30 additions & 3 deletions src/Bootloader/TemporalBridgeBootloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
use Temporal\Worker\WorkerFactoryInterface as TemporalWorkerFactoryInterface;
use Temporal\Worker\WorkerOptions;
use Temporal\WorkerFactory as TemporalWorkerFactory;
use Temporal\Client\ScheduleClient;
use Temporal\Client\ScheduleClientInterface;
use Temporal\Client\GRPC\ServiceClientInterface;

class TemporalBridgeBootloader extends Bootloader
{
Expand All @@ -57,8 +60,10 @@ public function defineSingletons(): array
DeclarationLocatorInterface::class => [self::class, 'initDeclarationLocator'],
WorkflowClientInterface::class => [self::class, 'initWorkflowClient'],
WorkersRegistryInterface::class => WorkersRegistry::class,
ScheduleClientInterface::class => [self::class, 'initScheduleClient'],
DataConverterInterface::class => [self::class, 'initDataConverter'],
PipelineProvider::class => [self::class, 'initPipelineProvider'],
ServiceClientInterface::class => [self::class, 'initServiceClient'],
];
}

Expand Down Expand Up @@ -89,8 +94,12 @@ protected function initConfig(EnvironmentInterface $env): void
[
'address' => $env->get('TEMPORAL_ADDRESS', '127.0.0.1:7233'),
'namespace' => 'App\\Endpoint\\Temporal\\Workflow',
'defaultWorker' => (string)$env->get('TEMPORAL_TASK_QUEUE', TemporalWorkerFactoryInterface::DEFAULT_TASK_QUEUE),
'defaultWorker' => (string)$env->get(
'TEMPORAL_TASK_QUEUE',
TemporalWorkerFactoryInterface::DEFAULT_TASK_QUEUE,
),
'workers' => [],
'clientOptions' => null,
],
);
}
Expand All @@ -99,10 +108,11 @@ protected function initWorkflowClient(
TemporalConfig $config,
DataConverterInterface $dataConverter,
PipelineProvider $pipelineProvider,
ServiceClientInterface $serviceClient,
): WorkflowClientInterface {
return new WorkflowClient(
serviceClient: ServiceClient::create($config->getAddress()),
options: (new ClientOptions())->withNamespace($config->getTemporalNamespace()),
serviceClient: $serviceClient,
options: $config->getClientOptions(),
converter: $dataConverter,
interceptorProvider: $pipelineProvider,
);
Expand Down Expand Up @@ -143,4 +153,21 @@ protected function initPipelineProvider(TemporalConfig $config, FactoryInterface

return new SimplePipelineProvider($interceptors);
}

protected function initServiceClient(TemporalConfig $config): ServiceClientInterface
{
return ServiceClient::create($config->getAddress());
}

protected function initScheduleClient(
TemporalConfig $config,
DataConverterInterface $dataConverter,
ServiceClientInterface $serviceClient,
): ScheduleClientInterface {
return new ScheduleClient(
serviceClient: $serviceClient,
options: $config->getClientOptions(),
converter: $dataConverter,
);
}
}
10 changes: 9 additions & 1 deletion src/Config/TemporalConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Spiral\Core\Container\Autowire;
use Spiral\Core\InjectableConfig;
use Temporal\Client\ClientOptions;
use Temporal\Exception\ExceptionInterceptorInterface;
use Temporal\Internal\Interceptor\Interceptor;
use Temporal\Worker\WorkerFactoryInterface;
Expand All @@ -25,7 +26,8 @@
* temporalNamespace: non-empty-string,
* defaultWorker: non-empty-string,
* workers: array<non-empty-string, WorkerOptions|TWorker>,
* interceptors?: TInterceptor[]
* interceptors?: TInterceptor[],
* clientOptions?: ClientOptions
* } $config
*/
final class TemporalConfig extends InjectableConfig
Expand All @@ -39,6 +41,7 @@ final class TemporalConfig extends InjectableConfig
'defaultWorker' => WorkerFactoryInterface::DEFAULT_TASK_QUEUE,
'workers' => [],
'interceptors' => [],
'clientOptions' => null,
];

/**
Expand Down Expand Up @@ -88,4 +91,9 @@ public function getInterceptors(): array
{
return $this->config['interceptors'] ?? [];
}

public function getClientOptions(): ClientOptions
{
return $this->config['clientOptions'] ?? (new ClientOptions())->withNamespace($this->getTemporalNamespace());
}
}
5 changes: 3 additions & 2 deletions tests/src/Attribute/AssignWorkerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Spiral\TemporalBridge\Tests\Attribute;

use PHPUnit\Framework\Attributes\DataProvider;
use Spiral\Attributes\Factory;
use Spiral\TemporalBridge\Attribute\AssignWorker;
use Spiral\TemporalBridge\Tests\App\SomeActivity;
Expand All @@ -13,15 +14,15 @@

final class AssignWorkerTest extends TestCase
{
/** @dataProvider assignWorkerDataProvider */
#[DataProvider(methodName: "assignWorkerDataProvider")]
public function testAssignWorkerAttribute(\ReflectionClass $class, ?AssignWorker $expected = null): void
{
$reader = (new Factory())->create();

$this->assertEquals($expected, $reader->firstClassMetadata($class, AssignWorker::class));
}

public function assignWorkerDataProvider(): \Traversable
public static function assignWorkerDataProvider(): \Traversable
{
yield [new \ReflectionClass(SomeActivity::class), new AssignWorker('worker1')];
yield [new \ReflectionClass(SomeWorkflow::class), new AssignWorker('worker2')];
Expand Down
20 changes: 20 additions & 0 deletions tests/src/Bootloader/TemporalBridgeBootloaderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
use Spiral\TemporalBridge\WorkerFactoryInterface;
use Spiral\TemporalBridge\WorkersRegistry;
use Spiral\TemporalBridge\WorkersRegistryInterface;
use Temporal\Client\GRPC\ServiceClient;
use Temporal\Client\GRPC\ServiceClientInterface;
use Temporal\Client\ScheduleClient;
use Temporal\Client\ScheduleClientInterface;
use Temporal\Client\WorkflowClient;
use Temporal\Client\WorkflowClientInterface;
use Temporal\DataConverter\DataConverter;
Expand All @@ -27,6 +31,22 @@

class TemporalBridgeBootloaderTest extends TestCase
{
public function testServiceClient(): void
{
$this->assertContainerBoundAsSingleton(
ServiceClientInterface::class,
ServiceClient::class,
);
}

public function testScheduleClient(): void
{
$this->assertContainerBoundAsSingleton(
ScheduleClientInterface::class,
ScheduleClient::class,
);
}

public function testTemporalWorkerFactory(): void
{
$this->assertContainerBoundAsSingleton(
Expand Down
21 changes: 21 additions & 0 deletions tests/src/Config/TemporalConfigTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Spiral\TemporalBridge\Config\TemporalConfig;
use Spiral\TemporalBridge\Tests\TestCase;
use Temporal\Client\ClientOptions;
use Temporal\Worker\WorkerFactoryInterface;
use Temporal\Worker\WorkerOptions;

Expand Down Expand Up @@ -113,4 +114,24 @@ public function testGetsWorkersIfItNotSet(): void

$this->assertSame([], $config->getWorkers());
}

public function testGetsUndefinedClientOptions(): void
{
$config = new TemporalConfig([
'temporalNamespace' => 'foo',
]);

$options = $config->getClientOptions();

$this->assertSame('foo', $options->namespace);
}

public function testGetsClientOptions(): void
{
$config = new TemporalConfig([
'clientOptions' => $options = new ClientOptions(),
]);

$this->assertSame($options, $config->getClientOptions());
}
}
7 changes: 3 additions & 4 deletions tests/src/WorkerFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Spiral\TemporalBridge\Tests;

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Spiral\Boot\FinalizerInterface;
use Spiral\Core\Container;
Expand Down Expand Up @@ -66,9 +67,7 @@ public function testCreateWithOptionsInArray(): void
$this->assertSame($worker, $factory->create('with-options-in-array'));
}

/**
* @dataProvider exceptionInterceptorsDataProvider
*/
#[DataProvider(methodName: 'exceptionInterceptorsDataProvider')]
public function testCreateWithExceptionInterceptor(string $name): void
{
$this->temporalWorkerFactory
Expand Down Expand Up @@ -125,7 +124,7 @@ public function testCreateWithAllOptions(): void
$this->assertSame($worker, $factory->create('all'));
}

public function exceptionInterceptorsDataProvider(): \Traversable
public static function exceptionInterceptorsDataProvider(): \Traversable
{
yield ['with-exception-interceptor-as-string'];
yield ['with-exception-interceptor-as-autowire'];
Expand Down

0 comments on commit 4e2f44f

Please sign in to comment.