Skip to content

Commit

Permalink
Use tokenizer listeners instead of tokenizer class locator to improve…
Browse files Browse the repository at this point in the history
… Spiral's performance during the bootloading stage.
  • Loading branch information
butschster committed Apr 12, 2024
1 parent 38be446 commit 8a69d92
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 73 deletions.
101 changes: 41 additions & 60 deletions src/Bootloader/TemporalBridgeBootloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
use Spiral\TemporalBridge\WorkerFactoryInterface;
use Spiral\TemporalBridge\WorkersRegistry;
use Spiral\TemporalBridge\WorkersRegistryInterface;
use Spiral\Tokenizer\ClassesInterface;
use Spiral\Tokenizer\TokenizerListenerRegistryInterface;
use Temporal\Client\GRPC\ServiceClient;
use Temporal\Client\WorkflowClient;
use Temporal\Client\WorkflowClientInterface;
Expand Down Expand Up @@ -56,15 +56,46 @@ public function defineDependencies(): array
public function defineSingletons(): array
{
return [
TemporalWorkerFactoryInterface::class => [self::class, 'initWorkerFactory'],
TemporalWorkerFactoryInterface::class => static fn(
DataConverterInterface $dataConverter,
): TemporalWorkerFactoryInterface => new TemporalWorkerFactory(
dataConverter: $dataConverter,
rpc: Goridge::create(),
),
WorkerFactoryInterface::class => WorkerFactory::class,
DeclarationLocatorInterface::class => [self::class, 'initDeclarationLocator'],
WorkflowClientInterface::class => [self::class, 'initWorkflowClient'],

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

WorkflowClientInterface::class => static fn(
TemporalConfig $config,
DataConverterInterface $dataConverter,
PipelineProvider $pipelineProvider,
ServiceClientInterface $serviceClient,
): WorkflowClientInterface => new WorkflowClient(
serviceClient: $serviceClient,
options: $config->getClientOptions(),
converter: $dataConverter,
interceptorProvider: $pipelineProvider,
),
WorkersRegistryInterface::class => WorkersRegistry::class,
ScheduleClientInterface::class => [self::class, 'initScheduleClient'],
DataConverterInterface::class => [self::class, 'initDataConverter'],

ScheduleClientInterface::class => static fn(
TemporalConfig $config,
DataConverterInterface $dataConverter,
ServiceClientInterface $serviceClient,
): ScheduleClientInterface => new ScheduleClient(
serviceClient: $serviceClient,
options: $config->getClientOptions(),
converter: $dataConverter,
),

DataConverterInterface::class => static fn() => DataConverter::createDefault(),
PipelineProvider::class => [self::class, 'initPipelineProvider'],
ServiceClientInterface::class => [self::class, 'initServiceClient'],
ServiceClientInterface::class => static fn(
TemporalConfig $config,
): ServiceClientInterface => ServiceClient::create($config->getAddress()),
];
}

Expand All @@ -78,9 +109,11 @@ public function init(
AbstractKernel $kernel,
EnvironmentInterface $env,
ConsoleBootloader $console,
TokenizerListenerRegistryInterface $tokenizer,
DeclarationLocator $locator,
): void {
$this->initConfig($env);

$tokenizer->addListener($locator);
$console->addCommand(Commands\InfoCommand::class);
$kernel->addDispatcher($this->factory->make(Dispatcher::class));
}
Expand Down Expand Up @@ -133,41 +166,6 @@ protected function initConfig(EnvironmentInterface $env): void
);
}

protected function initWorkflowClient(
TemporalConfig $config,
DataConverterInterface $dataConverter,
PipelineProvider $pipelineProvider,
ServiceClientInterface $serviceClient,
): WorkflowClientInterface {
return new WorkflowClient(
serviceClient: $serviceClient,
options: $config->getClientOptions(),
converter: $dataConverter,
interceptorProvider: $pipelineProvider,
);
}

protected function initDataConverter(): DataConverterInterface
{
return DataConverter::createDefault();
}

protected function initWorkerFactory(DataConverterInterface $dataConverter,): TemporalWorkerFactoryInterface
{
return new TemporalWorkerFactory(
dataConverter: $dataConverter,
rpc: Goridge::create(),
);
}

protected function initDeclarationLocator(ClassesInterface $classes,): DeclarationLocatorInterface
{
return new DeclarationLocator(
classes: $classes,
reader: new AttributeReader(),
);
}

protected function initPipelineProvider(TemporalConfig $config, FactoryInterface $factory): PipelineProvider
{
/** @var Interceptor[] $interceptors */
Expand All @@ -182,21 +180,4 @@ 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,
);
}
}
44 changes: 31 additions & 13 deletions src/DeclarationLocator.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,50 @@
namespace Spiral\TemporalBridge;

use Spiral\Attributes\ReaderInterface;
use Spiral\Tokenizer\ClassesInterface;
use Spiral\Core\Attribute\Singleton;
use Spiral\Tokenizer\Attribute\TargetAttribute;
use Spiral\Tokenizer\TokenizationListenerInterface;
use Temporal\Activity\ActivityInterface;
use Temporal\Workflow\WorkflowInterface;

final class DeclarationLocator implements DeclarationLocatorInterface
#[Singleton]
#[TargetAttribute(WorkflowInterface::class)]
#[TargetAttribute(ActivityInterface::class)]
final class DeclarationLocator implements DeclarationLocatorInterface, TokenizationListenerInterface
{
private array $declarations = [];

public function __construct(
private readonly ClassesInterface $classes,
private readonly ReaderInterface $reader
private readonly ReaderInterface $reader,
) {
}

public function getDeclarations(): iterable
{
foreach ($this->classes->getClasses() as $class) {
if ($class->isAbstract() || $class->isInterface() || $class->isEnum()) {
continue;
foreach ($this->declarations as $type => $classes) {
foreach ($classes as $class) {
yield $type => $class;
}
}
}

foreach (\array_merge($class->getInterfaces(), [$class]) as $type) {
if ($this->reader->firstClassMetadata($type, WorkflowInterface::class) !== null) {
yield WorkflowInterface::class => $class;
} elseif ($this->reader->firstClassMetadata($type, ActivityInterface::class) !== null) {
yield ActivityInterface::class => $class;
}
public function listen(\ReflectionClass $class): void
{
if ($class->isAbstract() || $class->isInterface() || $class->isEnum()) {
return;
}

foreach (\array_merge($class->getInterfaces(), [$class]) as $type) {
if ($this->reader->firstClassMetadata($type, WorkflowInterface::class) !== null) {
$this->declarations[WorkflowInterface::class][] = $class;
} elseif ($this->reader->firstClassMetadata($type, ActivityInterface::class) !== null) {
$this->declarations[ActivityInterface::class][] = $class;
}
}
}

public function finalize(): void
{
// do nothing
}
}

0 comments on commit 8a69d92

Please sign in to comment.