Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
],
"require": {
"php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0",
"patchlevel/event-sourcing": "^3.19.1",
"patchlevel/hydrator": "^1.21.2",
"patchlevel/event-sourcing": "^3.22.1",
"patchlevel/hydrator": "^1.24.3",
"symfony/cache": "^6.4.0 || ^7.0.0 || ^8.0.0",
"symfony/config": "^6.4.0 || ^7.0.0 || ^8.0.0",
"symfony/console": "^6.4.1 || ^7.0.1 || ^8.0.0",
Expand Down
570 changes: 290 additions & 280 deletions composer.lock

Large diffs are not rendered by default.

13 changes: 13 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,19 @@ patchlevel_event_sourcing:
If you want to learn more about custom headers, read the [library documentation](/docs/event-sourcing/latest/message/#custom-headers).
:::

## Metadata Cache

Aggregates, events and subscribers are described with attributes.
In production, meaning without `kernel.debug`, the registries and the metadata are cached
in php files in the build directory, which are created by `cache:warmup`.
This includes the hydrator metadata of your events, headers and aggregates with snapshots.
Until then, they are created on every request.
There is nothing to configure, the cache is renewed with every new build, e.g. by `cache:clear`.

:::note
With `kernel.debug`, nothing is cached, so that changes to your classes are picked up immediately.
:::

## Connection

You have to specify the connection url to the event store.
Expand Down
91 changes: 91 additions & 0 deletions src/CacheWarmer/HydratorMetadataCacheWarmer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?php

declare(strict_types=1);

namespace Patchlevel\EventSourcingBundle\CacheWarmer;

use Patchlevel\EventSourcing\Metadata\AggregateRoot\AggregateRootMetadataFactory;
use Patchlevel\EventSourcing\Metadata\AggregateRoot\AggregateRootRegistryFactory;
use Patchlevel\EventSourcing\Metadata\Event\EventRegistryFactory;
use Patchlevel\EventSourcing\Metadata\Message\MessageHeaderRegistry;
use Patchlevel\Hydrator\Metadata\MetadataFactory as HydratorMetadataFactory;
use Patchlevel\Hydrator\Metadata\Psr6MetadataFactory as Psr6HydratorMetadataFactory;
use Patchlevel\Hydrator\StackHydratorBuilder;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Cache\Adapter\NullAdapter;
use Symfony\Component\Cache\Adapter\PhpArrayAdapter;
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;

use function array_filter;
use function array_unique;
use function array_values;
use function is_file;

/**
* Collects the hydrator metadata of the events, headers and aggregates with snapshots with the uncached factories
* and dumps them into the php file that is read by the hydrator metadata cache.
*
* @internal
*/
final class HydratorMetadataCacheWarmer implements CacheWarmerInterface
{
/**
* @param list<string> $aggregatePaths
* @param list<string> $eventPaths
*/
public function __construct(
private readonly StackHydratorBuilder|HydratorMetadataFactory $hydrator,
private readonly AggregateRootRegistryFactory $aggregateRootRegistryFactory,
private readonly EventRegistryFactory $eventRegistryFactory,
private readonly AggregateRootMetadataFactory $aggregateRootMetadataFactory,
private readonly MessageHeaderRegistry $messageHeaderRegistry,
private readonly array $aggregatePaths,
private readonly array $eventPaths,
private readonly string $phpArrayFile,
) {
}

public function isOptional(): bool
{
return true;
}

/** @return array<string> classes to preload */
public function warmUp(string $cacheDir, string|null $buildDir = null): array
{
// the file lives in the build dir, so it is already up to date if it exists
if (is_file($this->phpArrayFile)) {
return [];
}

// without deep cloning, the array adapter keeps the objects as they are, which can then be exported
$cache = new ArrayAdapter(0, false);

Check warning on line 62 in src/CacheWarmer/HydratorMetadataCacheWarmer.php

View workflow job for this annotation

GitHub Actions / Mutation tests on diff (locked, 8.5, ubuntu-latest)

Escaped Mutant for Mutator "IncrementInteger": @@ @@ } // without deep cloning, the array adapter keeps the objects as they are, which can then be exported - $cache = new ArrayAdapter(0, false); + $cache = new ArrayAdapter(1, false); $hydratorMetadataFactory = $this->hydrator instanceof StackHydratorBuilder ? (clone $this->hydrator)->setCache($cache)->build()

Check warning on line 62 in src/CacheWarmer/HydratorMetadataCacheWarmer.php

View workflow job for this annotation

GitHub Actions / Mutation tests on diff (locked, 8.5, ubuntu-latest)

Escaped Mutant for Mutator "DecrementInteger": @@ @@ } // without deep cloning, the array adapter keeps the objects as they are, which can then be exported - $cache = new ArrayAdapter(0, false); + $cache = new ArrayAdapter(-1, false); $hydratorMetadataFactory = $this->hydrator instanceof StackHydratorBuilder ? (clone $this->hydrator)->setCache($cache)->build()

Check warning on line 62 in src/CacheWarmer/HydratorMetadataCacheWarmer.php

View workflow job for this annotation

GitHub Actions / Mutation tests (locked, 8.5, ubuntu-latest)

Escaped Mutant for Mutator "IncrementInteger": @@ @@ } // without deep cloning, the array adapter keeps the objects as they are, which can then be exported - $cache = new ArrayAdapter(0, false); + $cache = new ArrayAdapter(1, false); $hydratorMetadataFactory = $this->hydrator instanceof StackHydratorBuilder ? (clone $this->hydrator)->setCache($cache)->build()

Check warning on line 62 in src/CacheWarmer/HydratorMetadataCacheWarmer.php

View workflow job for this annotation

GitHub Actions / Mutation tests (locked, 8.5, ubuntu-latest)

Escaped Mutant for Mutator "DecrementInteger": @@ @@ } // without deep cloning, the array adapter keeps the objects as they are, which can then be exported - $cache = new ArrayAdapter(0, false); + $cache = new ArrayAdapter(-1, false); $hydratorMetadataFactory = $this->hydrator instanceof StackHydratorBuilder ? (clone $this->hydrator)->setCache($cache)->build()

$hydratorMetadataFactory = $this->hydrator instanceof StackHydratorBuilder
? (clone $this->hydrator)->setCache($cache)->build()

Check warning on line 65 in src/CacheWarmer/HydratorMetadataCacheWarmer.php

View workflow job for this annotation

GitHub Actions / Mutation tests on diff (locked, 8.5, ubuntu-latest)

Escaped Mutant for Mutator "CloneRemoval": @@ @@ $cache = new ArrayAdapter(0, false); $hydratorMetadataFactory = $this->hydrator instanceof StackHydratorBuilder - ? (clone $this->hydrator)->setCache($cache)->build() + ? ($this->hydrator)->setCache($cache)->build() : new Psr6HydratorMetadataFactory($this->hydrator, $cache); // aggregates are only hydrated for snapshots, events and headers are hydrated when they are (de)serialized

Check warning on line 65 in src/CacheWarmer/HydratorMetadataCacheWarmer.php

View workflow job for this annotation

GitHub Actions / Mutation tests (locked, 8.5, ubuntu-latest)

Escaped Mutant for Mutator "CloneRemoval": @@ @@ $cache = new ArrayAdapter(0, false); $hydratorMetadataFactory = $this->hydrator instanceof StackHydratorBuilder - ? (clone $this->hydrator)->setCache($cache)->build() + ? ($this->hydrator)->setCache($cache)->build() : new Psr6HydratorMetadataFactory($this->hydrator, $cache); // aggregates are only hydrated for snapshots, events and headers are hydrated when they are (de)serialized
: new Psr6HydratorMetadataFactory($this->hydrator, $cache);

// aggregates are only hydrated for snapshots, events and headers are hydrated when they are (de)serialized
$hydratedClasses = array_values($this->messageHeaderRegistry->headerClasses());

Check warning on line 69 in src/CacheWarmer/HydratorMetadataCacheWarmer.php

View workflow job for this annotation

GitHub Actions / Mutation tests on diff (locked, 8.5, ubuntu-latest)

Escaped Mutant for Mutator "UnwrapArrayValues": @@ @@ : new Psr6HydratorMetadataFactory($this->hydrator, $cache); // aggregates are only hydrated for snapshots, events and headers are hydrated when they are (de)serialized - $hydratedClasses = array_values($this->messageHeaderRegistry->headerClasses()); + $hydratedClasses = $this->messageHeaderRegistry->headerClasses(); foreach ($this->aggregateRootRegistryFactory->create($this->aggregatePaths)->aggregateClasses() as $aggregateClass) { if ($this->aggregateRootMetadataFactory->metadata($aggregateClass)->snapshot === null) {

Check warning on line 69 in src/CacheWarmer/HydratorMetadataCacheWarmer.php

View workflow job for this annotation

GitHub Actions / Mutation tests (locked, 8.5, ubuntu-latest)

Escaped Mutant for Mutator "UnwrapArrayValues": @@ @@ : new Psr6HydratorMetadataFactory($this->hydrator, $cache); // aggregates are only hydrated for snapshots, events and headers are hydrated when they are (de)serialized - $hydratedClasses = array_values($this->messageHeaderRegistry->headerClasses()); + $hydratedClasses = $this->messageHeaderRegistry->headerClasses(); foreach ($this->aggregateRootRegistryFactory->create($this->aggregatePaths)->aggregateClasses() as $aggregateClass) { if ($this->aggregateRootMetadataFactory->metadata($aggregateClass)->snapshot === null) {

foreach ($this->aggregateRootRegistryFactory->create($this->aggregatePaths)->aggregateClasses() as $aggregateClass) {
if ($this->aggregateRootMetadataFactory->metadata($aggregateClass)->snapshot === null) {
continue;
}

$hydratedClasses[] = $aggregateClass;
}

foreach ($this->eventRegistryFactory->create($this->eventPaths)->eventClasses() as $eventClass) {
$hydratedClasses[] = $eventClass;
}

foreach (array_unique($hydratedClasses) as $hydratedClass) {

Check warning on line 83 in src/CacheWarmer/HydratorMetadataCacheWarmer.php

View workflow job for this annotation

GitHub Actions / Mutation tests on diff (locked, 8.5, ubuntu-latest)

Escaped Mutant for Mutator "UnwrapArrayUnique": @@ @@ $hydratedClasses[] = $eventClass; } - foreach (array_unique($hydratedClasses) as $hydratedClass) { + foreach ($hydratedClasses as $hydratedClass) { $hydratorMetadataFactory->metadata($hydratedClass); }

Check warning on line 83 in src/CacheWarmer/HydratorMetadataCacheWarmer.php

View workflow job for this annotation

GitHub Actions / Mutation tests (locked, 8.5, ubuntu-latest)

Escaped Mutant for Mutator "UnwrapArrayUnique": @@ @@ $hydratedClasses[] = $eventClass; } - foreach (array_unique($hydratedClasses) as $hydratedClass) { + foreach ($hydratedClasses as $hydratedClass) { $hydratorMetadataFactory->metadata($hydratedClass); }
$hydratorMetadataFactory->metadata($hydratedClass);
}

$values = array_filter($cache->getValues(), static fn (mixed $value): bool => $value !== null);

Check warning on line 87 in src/CacheWarmer/HydratorMetadataCacheWarmer.php

View workflow job for this annotation

GitHub Actions / Mutation tests on diff (locked, 8.5, ubuntu-latest)

Escaped Mutant for Mutator "UnwrapArrayFilter": @@ @@ $hydratorMetadataFactory->metadata($hydratedClass); } - $values = array_filter($cache->getValues(), static fn (mixed $value): bool => $value !== null); + $values = $cache->getValues(); return (new PhpArrayAdapter($this->phpArrayFile, new NullAdapter()))->warmUp($values); }

Check warning on line 87 in src/CacheWarmer/HydratorMetadataCacheWarmer.php

View workflow job for this annotation

GitHub Actions / Mutation tests (locked, 8.5, ubuntu-latest)

Escaped Mutant for Mutator "UnwrapArrayFilter": @@ @@ $hydratorMetadataFactory->metadata($hydratedClass); } - $values = array_filter($cache->getValues(), static fn (mixed $value): bool => $value !== null); + $values = $cache->getValues(); return (new PhpArrayAdapter($this->phpArrayFile, new NullAdapter()))->warmUp($values); }

return (new PhpArrayAdapter($this->phpArrayFile, new NullAdapter()))->warmUp($values);
}
}
92 changes: 92 additions & 0 deletions src/CacheWarmer/MetadataCacheWarmer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?php

declare(strict_types=1);

namespace Patchlevel\EventSourcingBundle\CacheWarmer;

use Patchlevel\EventSourcing\Metadata\AggregateRoot\AggregateRootMetadataFactory;
use Patchlevel\EventSourcing\Metadata\AggregateRoot\AggregateRootRegistryFactory;
use Patchlevel\EventSourcing\Metadata\AggregateRoot\Psr6AggregateRootMetadataFactory;
use Patchlevel\EventSourcing\Metadata\AggregateRoot\Psr6AggregateRootRegistryFactory;
use Patchlevel\EventSourcing\Metadata\Event\EventMetadataFactory;
use Patchlevel\EventSourcing\Metadata\Event\EventRegistryFactory;
use Patchlevel\EventSourcing\Metadata\Event\Psr6EventMetadataFactory;
use Patchlevel\EventSourcing\Metadata\Event\Psr6EventRegistryFactory;
use Patchlevel\EventSourcing\Metadata\Subscriber\Psr6SubscriberMetadataFactory;
use Patchlevel\EventSourcing\Metadata\Subscriber\SubscriberMetadataFactory;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Cache\Adapter\NullAdapter;
use Symfony\Component\Cache\Adapter\PhpArrayAdapter;
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;

use function array_filter;
use function is_file;

/**
* Collects the registries and metadata of the aggregates, events and subscribers with the uncached factories
* and dumps them into the php file that is read by the metadata cache.
*
* @internal
*/
final class MetadataCacheWarmer implements CacheWarmerInterface
{
/**
* @param list<string> $aggregatePaths
* @param list<string> $eventPaths
* @param list<class-string> $subscriberClasses
*/
public function __construct(
private readonly AggregateRootRegistryFactory $aggregateRootRegistryFactory,
private readonly EventRegistryFactory $eventRegistryFactory,
private readonly AggregateRootMetadataFactory $aggregateRootMetadataFactory,
private readonly EventMetadataFactory $eventMetadataFactory,
private readonly SubscriberMetadataFactory $subscriberMetadataFactory,
private readonly array $aggregatePaths,
private readonly array $eventPaths,
private readonly array $subscriberClasses,
private readonly string $phpArrayFile,
) {
}

public function isOptional(): bool
{
return true;
}

/** @return array<string> classes to preload */
public function warmUp(string $cacheDir, string|null $buildDir = null): array
{
// the file lives in the build dir, so it is already up to date if it exists
if (is_file($this->phpArrayFile)) {
return [];
}

// without deep cloning, the array adapter keeps the objects as they are, which can then be exported
$cache = new ArrayAdapter(0, false);

Check warning on line 65 in src/CacheWarmer/MetadataCacheWarmer.php

View workflow job for this annotation

GitHub Actions / Mutation tests on diff (locked, 8.5, ubuntu-latest)

Escaped Mutant for Mutator "IncrementInteger": @@ @@ } // without deep cloning, the array adapter keeps the objects as they are, which can then be exported - $cache = new ArrayAdapter(0, false); + $cache = new ArrayAdapter(1, false); $aggregateRootRegistry = (new Psr6AggregateRootRegistryFactory($this->aggregateRootRegistryFactory, $cache)) ->create($this->aggregatePaths);

Check warning on line 65 in src/CacheWarmer/MetadataCacheWarmer.php

View workflow job for this annotation

GitHub Actions / Mutation tests on diff (locked, 8.5, ubuntu-latest)

Escaped Mutant for Mutator "DecrementInteger": @@ @@ } // without deep cloning, the array adapter keeps the objects as they are, which can then be exported - $cache = new ArrayAdapter(0, false); + $cache = new ArrayAdapter(-1, false); $aggregateRootRegistry = (new Psr6AggregateRootRegistryFactory($this->aggregateRootRegistryFactory, $cache)) ->create($this->aggregatePaths);

Check warning on line 65 in src/CacheWarmer/MetadataCacheWarmer.php

View workflow job for this annotation

GitHub Actions / Mutation tests (locked, 8.5, ubuntu-latest)

Escaped Mutant for Mutator "IncrementInteger": @@ @@ } // without deep cloning, the array adapter keeps the objects as they are, which can then be exported - $cache = new ArrayAdapter(0, false); + $cache = new ArrayAdapter(1, false); $aggregateRootRegistry = (new Psr6AggregateRootRegistryFactory($this->aggregateRootRegistryFactory, $cache)) ->create($this->aggregatePaths);

Check warning on line 65 in src/CacheWarmer/MetadataCacheWarmer.php

View workflow job for this annotation

GitHub Actions / Mutation tests (locked, 8.5, ubuntu-latest)

Escaped Mutant for Mutator "DecrementInteger": @@ @@ } // without deep cloning, the array adapter keeps the objects as they are, which can then be exported - $cache = new ArrayAdapter(0, false); + $cache = new ArrayAdapter(-1, false); $aggregateRootRegistry = (new Psr6AggregateRootRegistryFactory($this->aggregateRootRegistryFactory, $cache)) ->create($this->aggregatePaths);

$aggregateRootRegistry = (new Psr6AggregateRootRegistryFactory($this->aggregateRootRegistryFactory, $cache))
->create($this->aggregatePaths);
$eventRegistry = (new Psr6EventRegistryFactory($this->eventRegistryFactory, $cache))
->create($this->eventPaths);

$aggregateRootMetadataFactory = new Psr6AggregateRootMetadataFactory($this->aggregateRootMetadataFactory, $cache);
$eventMetadataFactory = new Psr6EventMetadataFactory($this->eventMetadataFactory, $cache);
$subscriberMetadataFactory = new Psr6SubscriberMetadataFactory($this->subscriberMetadataFactory, $cache);

foreach ($aggregateRootRegistry->aggregateClasses() as $aggregateClass) {
$aggregateRootMetadataFactory->metadata($aggregateClass);
}

foreach ($eventRegistry->eventClasses() as $eventClass) {
$eventMetadataFactory->metadata($eventClass);
}

foreach ($this->subscriberClasses as $subscriberClass) {
$subscriberMetadataFactory->metadata($subscriberClass);
}

$values = array_filter($cache->getValues(), static fn (mixed $value): bool => $value !== null);

Check warning on line 88 in src/CacheWarmer/MetadataCacheWarmer.php

View workflow job for this annotation

GitHub Actions / Mutation tests on diff (locked, 8.5, ubuntu-latest)

Escaped Mutant for Mutator "UnwrapArrayFilter": @@ @@ $subscriberMetadataFactory->metadata($subscriberClass); } - $values = array_filter($cache->getValues(), static fn (mixed $value): bool => $value !== null); + $values = $cache->getValues(); return (new PhpArrayAdapter($this->phpArrayFile, new NullAdapter()))->warmUp($values); }

Check warning on line 88 in src/CacheWarmer/MetadataCacheWarmer.php

View workflow job for this annotation

GitHub Actions / Mutation tests (locked, 8.5, ubuntu-latest)

Escaped Mutant for Mutator "UnwrapArrayFilter": @@ @@ $subscriberMetadataFactory->metadata($subscriberClass); } - $values = array_filter($cache->getValues(), static fn (mixed $value): bool => $value !== null); + $values = $cache->getValues(); return (new PhpArrayAdapter($this->phpArrayFile, new NullAdapter()))->warmUp($values); }

return (new PhpArrayAdapter($this->phpArrayFile, new NullAdapter()))->warmUp($values);
}
}
31 changes: 31 additions & 0 deletions src/DependencyInjection/AggregateRootRegistryResolver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

namespace Patchlevel\EventSourcingBundle\DependencyInjection;

use Patchlevel\EventSourcing\Metadata\AggregateRoot\AggregateRootRegistry;
use Patchlevel\EventSourcing\Metadata\AggregateRoot\AttributeAggregateRootRegistryFactory;
use Symfony\Component\DependencyInjection\ContainerBuilder;

/** @internal */
final class AggregateRootRegistryResolver
{
/**
* The registry is created from the configured paths instead of the service,
* because the service may depend on the metadata cache pool, which is not available while compiling.
*/
public static function resolve(ContainerBuilder $container): AggregateRootRegistry|null
{
if (!$container->hasDefinition(AggregateRootRegistry::class)) {
return null;
}

/** @var list<string> $paths */
$paths = $container->getParameterBag()->resolveValue(
$container->getDefinition(AggregateRootRegistry::class)->getArgument(0),
);

return (new AttributeAggregateRootRegistryFactory())->create($paths);
}
}
7 changes: 5 additions & 2 deletions src/DependencyInjection/CommandHandlerCompilerPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,17 @@
$container->getParameter('patchlevel_event_sourcing.aggregate_handlers.bus'),
);

/** @var AggregateRootRegistry $aggregateRootRegistry */
$aggregateRootRegistry = $container->get(AggregateRootRegistry::class);
$aggregateRootRegistry = AggregateRootRegistryResolver::resolve($container);

if (!$aggregateRootRegistry instanceof AggregateRootRegistry) {
return;
}

foreach ($aggregateRootRegistry->aggregateClasses() as $aggregateName => $aggregateClass) {
$parameterResolverId = sprintf('.event_sourcing.handler_parameter_resolver.%s', $aggregateName);

foreach (HandlerFinder::findInClass($aggregateClass) as $aggregateHandler) {
$handlerId = strtolower(sprintf('event_sourcing.handler.%s.%s', $aggregateName, $aggregateHandler->method));

Check warning on line 43 in src/DependencyInjection/CommandHandlerCompilerPass.php

View workflow job for this annotation

GitHub Actions / Mutation tests (locked, 8.5, ubuntu-latest)

Escaped Mutant for Mutator "UnwrapStrToLower": @@ @@ $parameterResolverId = sprintf('.event_sourcing.handler_parameter_resolver.%s', $aggregateName); foreach (HandlerFinder::findInClass($aggregateClass) as $aggregateHandler) { - $handlerId = strtolower(sprintf('event_sourcing.handler.%s.%s', $aggregateName, $aggregateHandler->method)); + $handlerId = sprintf('event_sourcing.handler.%s.%s', $aggregateName, $aggregateHandler->method); $handlerClass = $aggregateHandler->static ? CreateAggregateHandler::class : UpdateAggregateHandler::class; $container->register($handlerId, $handlerClass)
$handlerClass = $aggregateHandler->static ? CreateAggregateHandler::class : UpdateAggregateHandler::class;

$container->register($handlerId, $handlerClass)
Expand Down
7 changes: 5 additions & 2 deletions src/DependencyInjection/HandlerServiceLocatorCompilerPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,11 @@ public function process(ContainerBuilder $container): void
return;
}

/** @var AggregateRootRegistry $aggregateRootRegistry */
$aggregateRootRegistry = $container->get(AggregateRootRegistry::class);
$aggregateRootRegistry = AggregateRootRegistryResolver::resolve($container);

if (!$aggregateRootRegistry instanceof AggregateRootRegistry) {
return;
}

foreach ($aggregateRootRegistry->aggregateClasses() as $aggregateName => $aggregateClass) {
$parameterResolverId = sprintf('.event_sourcing.handler_parameter_resolver.%s', $aggregateName);
Expand Down
45 changes: 45 additions & 0 deletions src/DependencyInjection/MetadataCacheWarmerCompilerPass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

declare(strict_types=1);

namespace Patchlevel\EventSourcingBundle\DependencyInjection;

use Patchlevel\EventSourcingBundle\CacheWarmer\MetadataCacheWarmer;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

use function array_keys;
use function array_unique;
use function array_values;
use function class_exists;
use function is_string;

/**
* Passes the subscriber classes to the warmer, so that the subscribers do not have to be instantiated.
*
* @internal
*/
final class MetadataCacheWarmerCompilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container): void
{
if (!$container->hasDefinition(MetadataCacheWarmer::class)) {
return;
}

$subscriberClasses = [];

foreach (array_keys($container->findTaggedServiceIds('event_sourcing.subscriber')) as $id) {
$class = $container->getParameterBag()->resolveValue($container->getDefinition($id)->getClass());

if (!is_string($class) || !class_exists($class)) {
continue;
}

$subscriberClasses[] = $class;
}

$container->getDefinition(MetadataCacheWarmer::class)
->setArgument(7, array_values(array_unique($subscriberClasses)));

Check warning on line 43 in src/DependencyInjection/MetadataCacheWarmerCompilerPass.php

View workflow job for this annotation

GitHub Actions / Mutation tests on diff (locked, 8.5, ubuntu-latest)

Escaped Mutant for Mutator "UnwrapArrayValues": @@ @@ } $container->getDefinition(MetadataCacheWarmer::class) - ->setArgument(7, array_values(array_unique($subscriberClasses))); + ->setArgument(7, array_unique($subscriberClasses)); } }
}
}
Loading
Loading