From b0cb5be93e2251856f4d5635557ee08b5ce411e9 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Sun, 13 Oct 2024 19:29:17 +0200 Subject: [PATCH 1/5] TASK: Introduce `ContentRepository::catchupProjections` ... and remove `CatchUpTriggerWithSynchronousOption` which is currently hardcoded to `true` --- .../RaceTrackerCatchUpHook.php | 1 - .../Classes/ContentRepository.php | 9 +++ ...cessProjectionCatchUpCommandController.php | 37 --------- .../CatchUpTriggerWithSynchronousOption.php | 79 ------------------- .../SubprocessProjectionCatchUpTrigger.php | 43 ---------- ...processProjectionCatchUpTriggerFactory.php | 22 ------ 6 files changed, 9 insertions(+), 182 deletions(-) delete mode 100644 Neos.ContentRepositoryRegistry/Classes/Command/SubprocessProjectionCatchUpCommandController.php delete mode 100644 Neos.ContentRepositoryRegistry/Classes/Factory/ProjectionCatchUpTrigger/CatchUpTriggerWithSynchronousOption.php delete mode 100644 Neos.ContentRepositoryRegistry/Classes/Factory/ProjectionCatchUpTrigger/SubprocessProjectionCatchUpTrigger.php delete mode 100644 Neos.ContentRepositoryRegistry/Classes/Factory/ProjectionCatchUpTrigger/SubprocessProjectionCatchUpTriggerFactory.php diff --git a/Neos.ContentRepository.BehavioralTests/Classes/ProjectionRaceConditionTester/RaceTrackerCatchUpHook.php b/Neos.ContentRepository.BehavioralTests/Classes/ProjectionRaceConditionTester/RaceTrackerCatchUpHook.php index 3309f99d17d..039156ef9da 100644 --- a/Neos.ContentRepository.BehavioralTests/Classes/ProjectionRaceConditionTester/RaceTrackerCatchUpHook.php +++ b/Neos.ContentRepository.BehavioralTests/Classes/ProjectionRaceConditionTester/RaceTrackerCatchUpHook.php @@ -18,7 +18,6 @@ use Neos\ContentRepository\BehavioralTests\ProjectionRaceConditionTester\Dto\TraceEntryType; use Neos\ContentRepository\Core\EventStore\EventInterface; use Neos\ContentRepository\Core\Projection\CatchUpHookInterface; -use Neos\ContentRepositoryRegistry\Factory\ProjectionCatchUpTrigger\SubprocessProjectionCatchUpTrigger; use Neos\EventStore\Model\EventEnvelope; use Neos\Flow\Annotations as Flow; diff --git a/Neos.ContentRepository.Core/Classes/ContentRepository.php b/Neos.ContentRepository.Core/Classes/ContentRepository.php index d1262979d40..66e68ced477 100644 --- a/Neos.ContentRepository.Core/Classes/ContentRepository.php +++ b/Neos.ContentRepository.Core/Classes/ContentRepository.php @@ -200,6 +200,15 @@ public function catchUpProjection(string $projectionClassName, CatchUpOptions $o $catchUpHook?->onAfterCatchUp(); } + public function catchupProjections(): void + { + foreach ($this->projectionsAndCatchUpHooks->projections as $projection) { + // FIXME optimise by only loading required events once and not per projection + // see https://github.com/neos/neos-development-collection/pull/4988/ + $this->catchUpProjection($projection::class, CatchUpOptions::create()); + } + } + public function setUp(): void { $this->eventStore->setup(); diff --git a/Neos.ContentRepositoryRegistry/Classes/Command/SubprocessProjectionCatchUpCommandController.php b/Neos.ContentRepositoryRegistry/Classes/Command/SubprocessProjectionCatchUpCommandController.php deleted file mode 100644 index 6905c28646c..00000000000 --- a/Neos.ContentRepositoryRegistry/Classes/Command/SubprocessProjectionCatchUpCommandController.php +++ /dev/null @@ -1,37 +0,0 @@ -> $projectionClassName fully qualified class name of the projection to catch up - * @internal - */ - public function catchupCommand(string $contentRepository, string $projectionClassName): void - { - $contentRepositoryInstance = $this->contentRepositoryRegistry->get(ContentRepositoryId::fromString($contentRepository)); - $contentRepositoryInstance->catchUpProjection($projectionClassName, CatchUpOptions::create()); - } -} diff --git a/Neos.ContentRepositoryRegistry/Classes/Factory/ProjectionCatchUpTrigger/CatchUpTriggerWithSynchronousOption.php b/Neos.ContentRepositoryRegistry/Classes/Factory/ProjectionCatchUpTrigger/CatchUpTriggerWithSynchronousOption.php deleted file mode 100644 index d6b5342d1e9..00000000000 --- a/Neos.ContentRepositoryRegistry/Classes/Factory/ProjectionCatchUpTrigger/CatchUpTriggerWithSynchronousOption.php +++ /dev/null @@ -1,79 +0,0 @@ -contentRepositoryRegistry->get($this->contentRepositoryId); - foreach ($projections as $projection) { - $projectionClassName = get_class($projection); - $contentRepository->catchUpProjection($projectionClassName, CatchUpOptions::create()); - } - } else { - $this->inner->triggerCatchUp($projections); - } - } -} diff --git a/Neos.ContentRepositoryRegistry/Classes/Factory/ProjectionCatchUpTrigger/SubprocessProjectionCatchUpTrigger.php b/Neos.ContentRepositoryRegistry/Classes/Factory/ProjectionCatchUpTrigger/SubprocessProjectionCatchUpTrigger.php deleted file mode 100644 index f72541368a4..00000000000 --- a/Neos.ContentRepositoryRegistry/Classes/Factory/ProjectionCatchUpTrigger/SubprocessProjectionCatchUpTrigger.php +++ /dev/null @@ -1,43 +0,0 @@ - - */ - protected $flowSettings; - - public function __construct( - private readonly ContentRepositoryId $contentRepositoryId - ) { - } - - public function triggerCatchUp(Projections $projections): void - { - // modelled after https://github.com/neos/Neos.EventSourcing/blob/master/Classes/EventPublisher/JobQueueEventPublisher.php#L103 - // and https://github.com/Flowpack/jobqueue-common/blob/master/Classes/Queue/FakeQueue.php - foreach ($projections as $projection) { - Scripts::executeCommandAsync( - 'neos.contentrepositoryregistry:subprocessprojectioncatchup:catchup', - $this->flowSettings, - [ - 'contentRepositoryIdentifier' => $this->contentRepositoryId->value, - 'projectionClassName' => get_class($projection) - ] - ); - } - } -} diff --git a/Neos.ContentRepositoryRegistry/Classes/Factory/ProjectionCatchUpTrigger/SubprocessProjectionCatchUpTriggerFactory.php b/Neos.ContentRepositoryRegistry/Classes/Factory/ProjectionCatchUpTrigger/SubprocessProjectionCatchUpTriggerFactory.php deleted file mode 100644 index 8695f517d82..00000000000 --- a/Neos.ContentRepositoryRegistry/Classes/Factory/ProjectionCatchUpTrigger/SubprocessProjectionCatchUpTriggerFactory.php +++ /dev/null @@ -1,22 +0,0 @@ - $options */ - public function build(ContentRepositoryId $contentRepositoryId, array $options): ProjectionCatchUpTriggerInterface - { - return new CatchUpTriggerWithSynchronousOption( - $contentRepositoryId, - new SubprocessProjectionCatchUpTrigger($contentRepositoryId) - ); - } -} From 2a717fd693664e0704f36d874d36c87faaf815d1 Mon Sep 17 00:00:00 2001 From: Bastian Waidelich Date: Wed, 17 Apr 2024 17:33:09 +0200 Subject: [PATCH 2/5] Remove ProjectionCatchUpTriggerInterface and implementations ...for now --- .../Command/PerformanceMeasurementService.php | 4 ++-- .../Classes/ContentRepository.php | 2 +- .../Classes/EventStore/EventPersister.php | 19 ++++-------------- .../Factory/ContentRepositoryFactory.php | 3 --- .../Feature/WorkspaceCommandHandler.php | 4 ++++ .../ProjectionCatchUpTriggerInterface.php | 20 ------------------- .../Projection/WithMarkStaleInterface.php | 3 ++- .../src/StructureAdjustmentService.php | 2 +- ...ricCommandExecutionAndEventPublication.php | 2 +- .../Classes/ContentRepositoryRegistry.php | 14 ------------- ...ojectionCatchUpTriggerFactoryInterface.php | 12 ----------- .../Configuration/Settings.yaml | 3 --- 12 files changed, 15 insertions(+), 73 deletions(-) delete mode 100644 Neos.ContentRepository.Core/Classes/Projection/ProjectionCatchUpTriggerInterface.php delete mode 100644 Neos.ContentRepositoryRegistry/Classes/Factory/ProjectionCatchUpTrigger/ProjectionCatchUpTriggerFactoryInterface.php diff --git a/Neos.ContentRepository.BehavioralTests/Classes/Command/PerformanceMeasurementService.php b/Neos.ContentRepository.BehavioralTests/Classes/Command/PerformanceMeasurementService.php index 21c344d2f9d..378d5351dfe 100644 --- a/Neos.ContentRepository.BehavioralTests/Classes/Command/PerformanceMeasurementService.php +++ b/Neos.ContentRepository.BehavioralTests/Classes/Command/PerformanceMeasurementService.php @@ -96,7 +96,7 @@ public function createNodesForPerformanceTest(int $nodesPerLevel, int $levels): NodeAggregateClassification::CLASSIFICATION_ROOT, ); - $this->eventPersister->publishEvents(new EventsToPublish( + $this->eventPersister->publishEvents($this->contentRepository, new EventsToPublish( $this->contentStreamEventStream->getEventStreamName(), Events::with($rootNodeAggregateWasCreated), ExpectedVersion::ANY() @@ -106,7 +106,7 @@ public function createNodesForPerformanceTest(int $nodesPerLevel, int $levels): $sumSoFar = 0; $events = []; $this->createHierarchy($rootNodeAggregateId, 1, $levels, $nodesPerLevel, $sumSoFar, $events); - $this->eventPersister->publishEvents(new EventsToPublish( + $this->eventPersister->publishEvents($this->contentRepository, new EventsToPublish( $this->contentStreamEventStream->getEventStreamName(), Events::fromArray($events), ExpectedVersion::ANY() diff --git a/Neos.ContentRepository.Core/Classes/ContentRepository.php b/Neos.ContentRepository.Core/Classes/ContentRepository.php index 66e68ced477..09b3f20eca0 100644 --- a/Neos.ContentRepository.Core/Classes/ContentRepository.php +++ b/Neos.ContentRepository.Core/Classes/ContentRepository.php @@ -131,7 +131,7 @@ public function handle(CommandInterface $command): CommandResult $eventsToPublish->expectedVersion, ); - return $this->eventPersister->publishEvents($eventsToPublish); + return $this->eventPersister->publishEvents($this, $eventsToPublish); } diff --git a/Neos.ContentRepository.Core/Classes/EventStore/EventPersister.php b/Neos.ContentRepository.Core/Classes/EventStore/EventPersister.php index eef94b2a8f0..9cda3060224 100644 --- a/Neos.ContentRepository.Core/Classes/EventStore/EventPersister.php +++ b/Neos.ContentRepository.Core/Classes/EventStore/EventPersister.php @@ -5,10 +5,8 @@ namespace Neos\ContentRepository\Core\EventStore; use Neos\ContentRepository\Core\CommandHandler\CommandResult; -use Neos\ContentRepository\Core\CommandHandler\PendingProjections; -use Neos\ContentRepository\Core\Projection\ProjectionCatchUpTriggerInterface; +use Neos\ContentRepository\Core\ContentRepository; use Neos\ContentRepository\Core\Projection\Projections; -use Neos\ContentRepository\Core\Projection\WithMarkStaleInterface; use Neos\EventStore\EventStoreInterface; use Neos\EventStore\Exception\ConcurrencyException; use Neos\EventStore\Model\Events; @@ -23,7 +21,6 @@ { public function __construct( private EventStoreInterface $eventStore, - private ProjectionCatchUpTriggerInterface $projectionCatchUpTrigger, private EventNormalizer $eventNormalizer, private Projections $projections, ) { @@ -34,7 +31,7 @@ public function __construct( * @return CommandResult * @throws ConcurrencyException in case the expectedVersion does not match */ - public function publishEvents(EventsToPublish $eventsToPublish): CommandResult + public function publishEvents(ContentRepository $contentRepository, EventsToPublish $eventsToPublish): CommandResult { if ($eventsToPublish->events->isEmpty()) { return new CommandResult(); @@ -44,21 +41,13 @@ public function publishEvents(EventsToPublish $eventsToPublish): CommandResult $normalizedEvents = Events::fromArray( $eventsToPublish->events->map($this->eventNormalizer->normalize(...)) ); - $commitResult = $this->eventStore->commit( + $this->eventStore->commit( $eventsToPublish->streamName, $normalizedEvents, $eventsToPublish->expectedVersion ); - // for performance reasons, we do not want to update ALL projections all the time; but instead only - // the projections which are interested in the events from above. - // Further details can be found in the docs of PendingProjections. - $pendingProjections = PendingProjections::fromProjectionsAndEventsAndSequenceNumber( - $this->projections, - $eventsToPublish->events, - $commitResult->highestCommittedSequenceNumber - ); - $this->projectionCatchUpTrigger->triggerCatchUp($pendingProjections->projections); + $contentRepository->catchUpProjections(); return new CommandResult(); } } diff --git a/Neos.ContentRepository.Core/Classes/Factory/ContentRepositoryFactory.php b/Neos.ContentRepository.Core/Classes/Factory/ContentRepositoryFactory.php index bba7d784579..100298b988b 100644 --- a/Neos.ContentRepository.Core/Classes/Factory/ContentRepositoryFactory.php +++ b/Neos.ContentRepository.Core/Classes/Factory/ContentRepositoryFactory.php @@ -28,7 +28,6 @@ use Neos\ContentRepository\Core\Feature\WorkspaceCommandHandler; use Neos\ContentRepository\Core\Infrastructure\Property\PropertyConverter; use Neos\ContentRepository\Core\NodeType\NodeTypeManager; -use Neos\ContentRepository\Core\Projection\ProjectionCatchUpTriggerInterface; use Neos\ContentRepository\Core\Projection\ProjectionsAndCatchUpHooks; use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId; use Neos\ContentRepository\Core\SharedModel\User\UserIdProviderInterface; @@ -53,7 +52,6 @@ public function __construct( ContentDimensionSourceInterface $contentDimensionSource, Serializer $propertySerializer, ProjectionsAndCatchUpHooksFactory $projectionsAndCatchUpHooksFactory, - private readonly ProjectionCatchUpTriggerInterface $projectionCatchUpTrigger, private readonly UserIdProviderInterface $userIdProvider, private readonly ClockInterface $clock, ) { @@ -166,7 +164,6 @@ private function buildEventPersister(): EventPersister if (!$this->eventPersister) { $this->eventPersister = new EventPersister( $this->projectionFactoryDependencies->eventStore, - $this->projectionCatchUpTrigger, $this->projectionFactoryDependencies->eventNormalizer, $this->projectionsAndCatchUpHooks->projections, ); diff --git a/Neos.ContentRepository.Core/Classes/Feature/WorkspaceCommandHandler.php b/Neos.ContentRepository.Core/Classes/Feature/WorkspaceCommandHandler.php index 3789512c04d..47b8f384a17 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/WorkspaceCommandHandler.php +++ b/Neos.ContentRepository.Core/Classes/Feature/WorkspaceCommandHandler.php @@ -240,6 +240,7 @@ private function handlePublishWorkspace( $baseWorkspace = $this->requireBaseWorkspace($workspace, $commandHandlingDependencies->getWorkspaceFinder()); $this->publishContentStream( + $contentRepository, $workspace->currentContentStreamId, $baseWorkspace->workspaceName, $baseWorkspace->currentContentStreamId @@ -276,6 +277,7 @@ private function handlePublishWorkspace( * @throws \Exception */ private function publishContentStream( + ContentRepository $contentRepository, ContentStreamId $contentStreamId, WorkspaceName $baseWorkspaceName, ContentStreamId $baseContentStreamId, @@ -328,6 +330,7 @@ private function publishContentStream( } try { return $this->eventPersister->publishEvents( + $contentRepository, new EventsToPublish( $baseWorkspaceContentStreamName->getEventStreamName(), Events::fromArray($events), @@ -540,6 +543,7 @@ function () use ($matchingCommands, $commandHandlingDependencies, $baseWorkspace // 5) take EVENTS(MATCHING) and apply them to base WS. $this->publishContentStream( + $contentRepository, $command->contentStreamIdForMatchingPart, $baseWorkspace->workspaceName, $baseWorkspace->currentContentStreamId diff --git a/Neos.ContentRepository.Core/Classes/Projection/ProjectionCatchUpTriggerInterface.php b/Neos.ContentRepository.Core/Classes/Projection/ProjectionCatchUpTriggerInterface.php deleted file mode 100644 index 1fb20d34cbe..00000000000 --- a/Neos.ContentRepository.Core/Classes/Projection/ProjectionCatchUpTriggerInterface.php +++ /dev/null @@ -1,20 +0,0 @@ -remediation; $eventsToPublish = $remediation(); assert($eventsToPublish instanceof EventsToPublish); - $this->eventPersister->publishEvents($eventsToPublish); + $this->eventPersister->publishEvents($this->contentRepository, $eventsToPublish); } } } diff --git a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/GenericCommandExecutionAndEventPublication.php b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/GenericCommandExecutionAndEventPublication.php index c8e2118d5e4..bc49c4c9e37 100644 --- a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/GenericCommandExecutionAndEventPublication.php +++ b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/GenericCommandExecutionAndEventPublication.php @@ -140,7 +140,7 @@ protected function publishEvent(string $eventType, StreamName $streamName, array ->getValue($eventPersister); $event = $eventNormalizer->denormalize($artificiallyConstructedEvent); - $eventPersister->publishEvents(new EventsToPublish( + $eventPersister->publishEvents($this->currentContentRepository, new EventsToPublish( $streamName, Events::with($event), ExpectedVersion::ANY() diff --git a/Neos.ContentRepositoryRegistry/Classes/ContentRepositoryRegistry.php b/Neos.ContentRepositoryRegistry/Classes/ContentRepositoryRegistry.php index 0a4bf64988f..4f1f92433cb 100644 --- a/Neos.ContentRepositoryRegistry/Classes/ContentRepositoryRegistry.php +++ b/Neos.ContentRepositoryRegistry/Classes/ContentRepositoryRegistry.php @@ -14,7 +14,6 @@ use Neos\ContentRepository\Core\Projection\CatchUpHookFactoryInterface; use Neos\ContentRepository\Core\Projection\ContentGraph\ContentSubgraphInterface; use Neos\ContentRepository\Core\Projection\ContentGraph\Node; -use Neos\ContentRepository\Core\Projection\ProjectionCatchUpTriggerInterface; use Neos\ContentRepository\Core\Projection\ProjectionFactoryInterface; use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId; use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryIds; @@ -25,7 +24,6 @@ use Neos\ContentRepositoryRegistry\Factory\ContentDimensionSource\ContentDimensionSourceFactoryInterface; use Neos\ContentRepositoryRegistry\Factory\EventStore\EventStoreFactoryInterface; use Neos\ContentRepositoryRegistry\Factory\NodeTypeManager\NodeTypeManagerFactoryInterface; -use Neos\ContentRepositoryRegistry\Factory\ProjectionCatchUpTrigger\ProjectionCatchUpTriggerFactoryInterface; use Neos\ContentRepositoryRegistry\Factory\UserIdProvider\UserIdProviderFactoryInterface; use Neos\ContentRepositoryRegistry\SubgraphCachingInMemory\ContentSubgraphWithRuntimeCaches; use Neos\ContentRepositoryRegistry\SubgraphCachingInMemory\SubgraphCachePool; @@ -170,7 +168,6 @@ private function buildFactory(ContentRepositoryId $contentRepositoryId): Content $this->buildContentDimensionSource($contentRepositoryId, $contentRepositorySettings), $this->buildPropertySerializer($contentRepositoryId, $contentRepositorySettings), $this->buildProjectionsFactory($contentRepositoryId, $contentRepositorySettings), - $this->buildProjectionCatchUpTrigger($contentRepositoryId, $contentRepositorySettings), $this->buildUserIdProvider($contentRepositoryId, $contentRepositorySettings), $clock ); @@ -263,17 +260,6 @@ private function buildProjectionsFactory(ContentRepositoryId $contentRepositoryI return $projectionsFactory; } - /** @param array $contentRepositorySettings */ - private function buildProjectionCatchUpTrigger(ContentRepositoryId $contentRepositoryId, array $contentRepositorySettings): ProjectionCatchUpTriggerInterface - { - isset($contentRepositorySettings['projectionCatchUpTrigger']['factoryObjectName']) || throw InvalidConfigurationException::fromMessage('Content repository "%s" does not have projectionCatchUpTrigger.factoryObjectName configured.', $contentRepositoryId->value); - $projectionCatchUpTriggerFactory = $this->objectManager->get($contentRepositorySettings['projectionCatchUpTrigger']['factoryObjectName']); - if (!$projectionCatchUpTriggerFactory instanceof ProjectionCatchUpTriggerFactoryInterface) { - throw InvalidConfigurationException::fromMessage('projectionCatchUpTrigger.factoryObjectName for content repository "%s" is not an instance of %s but %s.', $contentRepositoryId->value, ProjectionCatchUpTriggerFactoryInterface::class, get_debug_type($projectionCatchUpTriggerFactory)); - } - return $projectionCatchUpTriggerFactory->build($contentRepositoryId, $contentRepositorySettings['projectionCatchUpTrigger']['options'] ?? []); - } - /** @param array $contentRepositorySettings */ private function buildUserIdProvider(ContentRepositoryId $contentRepositoryId, array $contentRepositorySettings): UserIdProviderInterface { diff --git a/Neos.ContentRepositoryRegistry/Classes/Factory/ProjectionCatchUpTrigger/ProjectionCatchUpTriggerFactoryInterface.php b/Neos.ContentRepositoryRegistry/Classes/Factory/ProjectionCatchUpTrigger/ProjectionCatchUpTriggerFactoryInterface.php deleted file mode 100644 index 5f73b1859ad..00000000000 --- a/Neos.ContentRepositoryRegistry/Classes/Factory/ProjectionCatchUpTrigger/ProjectionCatchUpTriggerFactoryInterface.php +++ /dev/null @@ -1,12 +0,0 @@ - $options */ - public function build(ContentRepositoryId $contentRepositoryId, array $options): ProjectionCatchUpTriggerInterface; -} diff --git a/Neos.ContentRepositoryRegistry/Configuration/Settings.yaml b/Neos.ContentRepositoryRegistry/Configuration/Settings.yaml index 70b0fe0c5d8..a97a2b44931 100644 --- a/Neos.ContentRepositoryRegistry/Configuration/Settings.yaml +++ b/Neos.ContentRepositoryRegistry/Configuration/Settings.yaml @@ -31,9 +31,6 @@ Neos: contentDimensionSource: factoryObjectName: Neos\ContentRepositoryRegistry\Factory\ContentDimensionSource\ConfigurationBasedContentDimensionSourceFactory - projectionCatchUpTrigger: - factoryObjectName: Neos\ContentRepositoryRegistry\Factory\ProjectionCatchUpTrigger\SubprocessProjectionCatchUpTriggerFactory - userIdProvider: factoryObjectName: Neos\ContentRepositoryRegistry\Factory\UserIdProvider\StaticUserIdProviderFactory From ddac2c45787eb8013e0ae71f765c943eafa11ab2 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Sun, 13 Oct 2024 19:20:57 +0200 Subject: [PATCH 3/5] TASK: Fixup cherry-pick and adjust to use `CommandHandlingDependencies` --- .../Classes/CommandHandlingDependencies.php | 13 +++++++++++-- .../Classes/ContentRepository.php | 2 +- .../Classes/EventStore/EventPersister.php | 1 - .../Classes/Factory/ContentRepositoryFactory.php | 2 -- .../Classes/Feature/WorkspaceCommandHandler.php | 14 ++++++-------- .../src/StructureAdjustmentService.php | 2 +- .../GraphProjectorCatchUpHookForCacheFlushing.php | 4 +--- 7 files changed, 20 insertions(+), 18 deletions(-) diff --git a/Neos.ContentRepository.Core/Classes/CommandHandlingDependencies.php b/Neos.ContentRepository.Core/Classes/CommandHandlingDependencies.php index c0b5270cc37..732681a8ee4 100644 --- a/Neos.ContentRepository.Core/Classes/CommandHandlingDependencies.php +++ b/Neos.ContentRepository.Core/Classes/CommandHandlingDependencies.php @@ -16,6 +16,8 @@ use Neos\ContentRepository\Core\CommandHandler\CommandInterface; use Neos\ContentRepository\Core\CommandHandler\CommandResult; +use Neos\ContentRepository\Core\EventStore\EventPersister; +use Neos\ContentRepository\Core\EventStore\EventsToPublish; use Neos\ContentRepository\Core\Projection\ContentGraph\ContentGraphInterface; use Neos\ContentRepository\Core\Projection\ContentStream\ContentStreamFinder; use Neos\ContentRepository\Core\Projection\Workspace\WorkspaceFinder; @@ -37,8 +39,10 @@ final class CommandHandlingDependencies */ private array $overridenContentGraphInstances = []; - public function __construct(private readonly ContentRepository $contentRepository) - { + public function __construct( + private readonly ContentRepository $contentRepository, + private readonly EventPersister $eventPersister + ) { } public function handle(CommandInterface $command): CommandResult @@ -46,6 +50,11 @@ public function handle(CommandInterface $command): CommandResult return $this->contentRepository->handle($command); } + public function publishEvents(EventsToPublish $eventsToPublish): void + { + $this->eventPersister->publishEvents($this->contentRepository, $eventsToPublish); + } + public function getWorkspaceFinder(): WorkspaceFinder { return $this->contentRepository->getWorkspaceFinder(); diff --git a/Neos.ContentRepository.Core/Classes/ContentRepository.php b/Neos.ContentRepository.Core/Classes/ContentRepository.php index 09b3f20eca0..c6699fde16a 100644 --- a/Neos.ContentRepository.Core/Classes/ContentRepository.php +++ b/Neos.ContentRepository.Core/Classes/ContentRepository.php @@ -87,7 +87,7 @@ public function __construct( private readonly UserIdProviderInterface $userIdProvider, private readonly ClockInterface $clock, ) { - $this->commandHandlingDependencies = new CommandHandlingDependencies($this); + $this->commandHandlingDependencies = new CommandHandlingDependencies($this, $eventPersister); } /** diff --git a/Neos.ContentRepository.Core/Classes/EventStore/EventPersister.php b/Neos.ContentRepository.Core/Classes/EventStore/EventPersister.php index 9cda3060224..f941a08d583 100644 --- a/Neos.ContentRepository.Core/Classes/EventStore/EventPersister.php +++ b/Neos.ContentRepository.Core/Classes/EventStore/EventPersister.php @@ -22,7 +22,6 @@ public function __construct( private EventStoreInterface $eventStore, private EventNormalizer $eventNormalizer, - private Projections $projections, ) { } diff --git a/Neos.ContentRepository.Core/Classes/Factory/ContentRepositoryFactory.php b/Neos.ContentRepository.Core/Classes/Factory/ContentRepositoryFactory.php index 100298b988b..3c81c0adb56 100644 --- a/Neos.ContentRepository.Core/Classes/Factory/ContentRepositoryFactory.php +++ b/Neos.ContentRepository.Core/Classes/Factory/ContentRepositoryFactory.php @@ -135,7 +135,6 @@ private function buildCommandBus(): CommandBus new ContentStreamCommandHandler( ), new WorkspaceCommandHandler( - $this->buildEventPersister(), $this->projectionFactoryDependencies->eventStore, $this->projectionFactoryDependencies->eventNormalizer, ), @@ -165,7 +164,6 @@ private function buildEventPersister(): EventPersister $this->eventPersister = new EventPersister( $this->projectionFactoryDependencies->eventStore, $this->projectionFactoryDependencies->eventNormalizer, - $this->projectionsAndCatchUpHooks->projections, ); } return $this->eventPersister; diff --git a/Neos.ContentRepository.Core/Classes/Feature/WorkspaceCommandHandler.php b/Neos.ContentRepository.Core/Classes/Feature/WorkspaceCommandHandler.php index 47b8f384a17..3a37f674a7f 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/WorkspaceCommandHandler.php +++ b/Neos.ContentRepository.Core/Classes/Feature/WorkspaceCommandHandler.php @@ -87,7 +87,6 @@ final readonly class WorkspaceCommandHandler implements CommandHandlerInterface { public function __construct( - private EventPersister $eventPersister, private EventStoreInterface $eventStore, private EventNormalizer $eventNormalizer, ) { @@ -240,7 +239,7 @@ private function handlePublishWorkspace( $baseWorkspace = $this->requireBaseWorkspace($workspace, $commandHandlingDependencies->getWorkspaceFinder()); $this->publishContentStream( - $contentRepository, + $commandHandlingDependencies, $workspace->currentContentStreamId, $baseWorkspace->workspaceName, $baseWorkspace->currentContentStreamId @@ -277,11 +276,11 @@ private function handlePublishWorkspace( * @throws \Exception */ private function publishContentStream( - ContentRepository $contentRepository, + CommandHandlingDependencies $commandHandlingDependencies, ContentStreamId $contentStreamId, WorkspaceName $baseWorkspaceName, ContentStreamId $baseContentStreamId, - ): ?CommandResult { + ): void { $baseWorkspaceContentStreamName = ContentStreamEventStreamName::fromContentStreamId( $baseContentStreamId ); @@ -326,11 +325,10 @@ private function publishContentStream( } if (count($events) === 0) { - return null; + return; } try { - return $this->eventPersister->publishEvents( - $contentRepository, + $commandHandlingDependencies->publishEvents( new EventsToPublish( $baseWorkspaceContentStreamName->getEventStreamName(), Events::fromArray($events), @@ -543,7 +541,7 @@ function () use ($matchingCommands, $commandHandlingDependencies, $baseWorkspace // 5) take EVENTS(MATCHING) and apply them to base WS. $this->publishContentStream( - $contentRepository, + $commandHandlingDependencies, $command->contentStreamIdForMatchingPart, $baseWorkspace->workspaceName, $baseWorkspace->currentContentStreamId diff --git a/Neos.ContentRepository.StructureAdjustment/src/StructureAdjustmentService.php b/Neos.ContentRepository.StructureAdjustment/src/StructureAdjustmentService.php index 898a2b1c76b..6211faa4751 100644 --- a/Neos.ContentRepository.StructureAdjustment/src/StructureAdjustmentService.php +++ b/Neos.ContentRepository.StructureAdjustment/src/StructureAdjustmentService.php @@ -38,7 +38,7 @@ class StructureAdjustmentService implements ContentRepositoryServiceInterface private readonly ContentGraphInterface $liveContentGraph; public function __construct( - ContentRepository $contentRepository, + private readonly ContentRepository $contentRepository, private readonly EventPersister $eventPersister, NodeTypeManager $nodeTypeManager, InterDimensionalVariationGraph $interDimensionalVariationGraph, diff --git a/Neos.Neos/Classes/Fusion/Cache/GraphProjectorCatchUpHookForCacheFlushing.php b/Neos.Neos/Classes/Fusion/Cache/GraphProjectorCatchUpHookForCacheFlushing.php index e3e8bcfe461..19ffd145d04 100644 --- a/Neos.Neos/Classes/Fusion/Cache/GraphProjectorCatchUpHookForCacheFlushing.php +++ b/Neos.Neos/Classes/Fusion/Cache/GraphProjectorCatchUpHookForCacheFlushing.php @@ -49,9 +49,7 @@ * is not needed: * * By calling {@see self::disabled(\Closure)} in your code, all projection updates - * will never trigger catch up hooks. This will only work when - * {@see CatchUpTriggerWithSynchronousOption::synchronously()} is called, - * as otherwise this subprocess won't be called. + * will never trigger catch up hooks. * * * projection update From 0b6e2faec8946e25840a03afbb9c0c44c8e0ed7d Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Mon, 14 Oct 2024 22:02:11 +0200 Subject: [PATCH 4/5] TASK: Remove `PendingProjections` as we run the cr in sync mode --- .../CommandHandler/PendingProjections.php | 133 ------------------ .../Classes/EventStore/EventPersister.php | 1 - 2 files changed, 134 deletions(-) delete mode 100644 Neos.ContentRepository.Core/Classes/CommandHandler/PendingProjections.php diff --git a/Neos.ContentRepository.Core/Classes/CommandHandler/PendingProjections.php b/Neos.ContentRepository.Core/Classes/CommandHandler/PendingProjections.php deleted file mode 100644 index 9a96085efe1..00000000000 --- a/Neos.ContentRepository.Core/Classes/CommandHandler/PendingProjections.php +++ /dev/null @@ -1,133 +0,0 @@ -> $projections - * @param array $sequenceNumberPerProjection - */ - public function __construct( - public Projections $projections, - private array $sequenceNumberPerProjection, - ) { - } - - public static function empty(): self - { - return new self(Projections::empty(), []); - } - - public static function fromProjectionsAndEventsAndSequenceNumber( - Projections $allProjections, - Events $events, - SequenceNumber $highestCommittedSequenceNumber - ): self { - $sequenceNumberInteger = $highestCommittedSequenceNumber->value - $events->count() + 1; - $pendingProjectionsArray = []; - $sequenceNumberPerProjection = []; - foreach ($events as $event) { - if ($event instanceof DecoratedEvent) { - $event = $event->innerEvent; - } - foreach ($allProjections as $projection) { - if ($projection->canHandle($event)) { - $sequenceNumberPerProjection[$projection::class] = $sequenceNumberInteger; - if (!in_array($projection, $pendingProjectionsArray, true)) { - $pendingProjectionsArray[] = $projection; - } - } - } - $sequenceNumberInteger++; - } - return new self(Projections::fromArray($pendingProjectionsArray), $sequenceNumberPerProjection); - } - - /** - * @param ProjectionInterface $projection - * @return SequenceNumber - */ - public function getExpectedSequenceNumber(ProjectionInterface $projection): SequenceNumber - { - if (!array_key_exists($projection::class, $this->sequenceNumberPerProjection)) { - throw new \InvalidArgumentException( - sprintf('Projection of class "%s" is not pending', $projection::class), - 1652252976 - ); - } - return SequenceNumber::fromInteger($this->sequenceNumberPerProjection[$projection::class]); - } -} diff --git a/Neos.ContentRepository.Core/Classes/EventStore/EventPersister.php b/Neos.ContentRepository.Core/Classes/EventStore/EventPersister.php index f941a08d583..4641ccbb1a4 100644 --- a/Neos.ContentRepository.Core/Classes/EventStore/EventPersister.php +++ b/Neos.ContentRepository.Core/Classes/EventStore/EventPersister.php @@ -6,7 +6,6 @@ use Neos\ContentRepository\Core\CommandHandler\CommandResult; use Neos\ContentRepository\Core\ContentRepository; -use Neos\ContentRepository\Core\Projection\Projections; use Neos\EventStore\EventStoreInterface; use Neos\EventStore\Exception\ConcurrencyException; use Neos\EventStore\Model\Events; From bff61f3560831c0747480531b4ce93bc318e0991 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Wed, 16 Oct 2024 17:38:29 +0200 Subject: [PATCH 5/5] !!! TASK: Declare `ProjectionService` as api to reset projections instead of ContentRepository --- .../Command/PerformanceMeasurementService.php | 6 ++-- .../PerformanceMeasurementServiceFactory.php | 3 +- .../CRBehavioralTestsSubjectProvider.php | 6 +++- .../Classes/Projection/Projections.php | 11 +++++- .../Classes/Service/ProjectionService.php | 34 +++++++++---------- .../Service/ProjectionServiceFactory.php | 24 +++++++++++++ .../Classes/Command/CrCommandController.php | 6 ++-- .../Features/Bootstrap/CRTestSuiteTrait.php | 8 +++-- .../Behavior/CRRegistrySubjectProvider.php | 6 +++- .../Classes/Command/CrCommandController.php | 4 +-- .../ProjectionReplayServiceFactory.php | 30 ---------------- .../Classes/Command/CrCommandController.php | 6 ++-- phpstan-baseline.neon | 4 --- 13 files changed, 80 insertions(+), 68 deletions(-) rename Neos.ContentRepositoryRegistry/Classes/Service/ProjectionReplayService.php => Neos.ContentRepository.Core/Classes/Service/ProjectionService.php (73%) create mode 100644 Neos.ContentRepository.Core/Classes/Service/ProjectionServiceFactory.php delete mode 100644 Neos.ContentRepositoryRegistry/Classes/Service/ProjectionReplayServiceFactory.php diff --git a/Neos.ContentRepository.BehavioralTests/Classes/Command/PerformanceMeasurementService.php b/Neos.ContentRepository.BehavioralTests/Classes/Command/PerformanceMeasurementService.php index 378d5351dfe..b11139eb9bb 100644 --- a/Neos.ContentRepository.BehavioralTests/Classes/Command/PerformanceMeasurementService.php +++ b/Neos.ContentRepository.BehavioralTests/Classes/Command/PerformanceMeasurementService.php @@ -32,6 +32,7 @@ use Neos\ContentRepository\Core\Feature\RootNodeCreation\Event\RootNodeAggregateWithNodeWasCreated; use Neos\ContentRepository\Core\Feature\WorkspaceCreation\Command\CreateRootWorkspace; use Neos\ContentRepository\Core\NodeType\NodeTypeName; +use Neos\ContentRepository\Core\Projection\Projections; use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateClassification; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId; @@ -53,7 +54,8 @@ public function __construct( private readonly EventPersister $eventPersister, private readonly ContentRepository $contentRepository, private readonly Connection $connection, - private readonly ContentRepositoryId $contentRepositoryId + private readonly ContentRepositoryId $contentRepositoryId, + private readonly Projections $projections, ) { $this->contentStreamId = contentStreamId::fromString('cs-identifier'); $this->workspaceName = WorkspaceName::fromString('some-workspace'); @@ -74,7 +76,7 @@ public function removeEverything(): void { $eventTableName = DoctrineEventStoreFactory::databaseTableName($this->contentRepositoryId); $this->connection->executeStatement('TRUNCATE ' . $this->connection->quoteIdentifier($eventTableName)); - $this->contentRepository->resetProjectionStates(); + $this->projections->resetAll(); } public function createNodesForPerformanceTest(int $nodesPerLevel, int $levels): void diff --git a/Neos.ContentRepository.BehavioralTests/Classes/Command/PerformanceMeasurementServiceFactory.php b/Neos.ContentRepository.BehavioralTests/Classes/Command/PerformanceMeasurementServiceFactory.php index 1b3c9611228..23d7fb4a87b 100644 --- a/Neos.ContentRepository.BehavioralTests/Classes/Command/PerformanceMeasurementServiceFactory.php +++ b/Neos.ContentRepository.BehavioralTests/Classes/Command/PerformanceMeasurementServiceFactory.php @@ -36,7 +36,8 @@ public function build( $serviceFactoryDependencies->eventPersister, $serviceFactoryDependencies->contentRepository, $this->connection, - $serviceFactoryDependencies->contentRepositoryId + $serviceFactoryDependencies->contentRepositoryId, + $serviceFactoryDependencies->projections, ); } } diff --git a/Neos.ContentRepository.BehavioralTests/Classes/TestSuite/Behavior/CRBehavioralTestsSubjectProvider.php b/Neos.ContentRepository.BehavioralTests/Classes/TestSuite/Behavior/CRBehavioralTestsSubjectProvider.php index 19eb183ff16..22eaf714546 100644 --- a/Neos.ContentRepository.BehavioralTests/Classes/TestSuite/Behavior/CRBehavioralTestsSubjectProvider.php +++ b/Neos.ContentRepository.BehavioralTests/Classes/TestSuite/Behavior/CRBehavioralTestsSubjectProvider.php @@ -18,6 +18,8 @@ use Behat\Gherkin\Node\TableNode; use Doctrine\DBAL\Connection; use Neos\ContentRepository\Core\ContentRepository; +use Neos\ContentRepository\Core\Service\ProjectionService; +use Neos\ContentRepository\Core\Service\ProjectionServiceFactory; use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId; use Neos\ContentRepository\TestSuite\Behavior\Features\Bootstrap\Helpers\GherkinTableNodeBasedContentDimensionSource; use Neos\EventStore\EventStoreInterface; @@ -179,7 +181,9 @@ protected function setUpContentRepository(ContentRepositoryId $contentRepository $databaseConnection = (new \ReflectionClass($eventStore))->getProperty('connection')->getValue($eventStore); $eventTableName = sprintf('cr_%s_events', $contentRepositoryId->value); $databaseConnection->executeStatement('TRUNCATE ' . $eventTableName); - $contentRepository->resetProjectionStates(); + /** @var ProjectionService $projectionService */ + $projectionService = $this->contentRepositoryRegistry->buildService($contentRepositoryId, $this->getObject(ProjectionServiceFactory::class)); + $projectionService->resetAllProjections(); return $contentRepository; } diff --git a/Neos.ContentRepository.Core/Classes/Projection/Projections.php b/Neos.ContentRepository.Core/Classes/Projection/Projections.php index 0bc7dffec20..b835a78b2b7 100644 --- a/Neos.ContentRepository.Core/Classes/Projection/Projections.php +++ b/Neos.ContentRepository.Core/Classes/Projection/Projections.php @@ -4,11 +4,13 @@ namespace Neos\ContentRepository\Core\Projection; +use Neos\ContentRepository\Core\Service\ProjectionService; + /** * An immutable set of Content Repository projections ({@see ProjectionInterface} * * @implements \IteratorAggregate - * @internal + * @internal only used by framework code or services such as {@see ProjectionService} */ final class Projections implements \IteratorAggregate, \Countable { @@ -86,6 +88,13 @@ public function getClassNames(): array return array_keys($this->projections); } + public function resetAll(): void + { + foreach ($this->projections as $projection) { + $projection->reset(); + } + } + /** * @return \Traversable> */ diff --git a/Neos.ContentRepositoryRegistry/Classes/Service/ProjectionReplayService.php b/Neos.ContentRepository.Core/Classes/Service/ProjectionService.php similarity index 73% rename from Neos.ContentRepositoryRegistry/Classes/Service/ProjectionReplayService.php rename to Neos.ContentRepository.Core/Classes/Service/ProjectionService.php index 00a946be01a..2978f7d0597 100644 --- a/Neos.ContentRepositoryRegistry/Classes/Service/ProjectionReplayService.php +++ b/Neos.ContentRepository.Core/Classes/Service/ProjectionService.php @@ -1,9 +1,11 @@ resolveProjectionClassName($projectionAliasOrClassName); - $this->contentRepository->resetProjectionState($projectionClassName); - $this->contentRepository->catchUpProjection($projectionClassName, $options); + $projection = $this->resolveProjection($projectionAliasOrClassName); + $projection->reset(); + $this->contentRepository->catchUpProjection($projection::class, $options); } public function replayAllProjections(CatchUpOptions $options, ?\Closure $progressCallback = null): void @@ -41,16 +40,15 @@ public function replayAllProjections(CatchUpOptions $options, ?\Closure $progres if ($progressCallback) { $progressCallback($classNamesAndAlias['alias']); } - $this->contentRepository->resetProjectionState($classNamesAndAlias['className']); - $this->contentRepository->catchUpProjection($classNamesAndAlias['className'], $options); + $projection = $this->projections->get($classNamesAndAlias['className']); + $projection->reset(); + $this->contentRepository->catchUpProjection($projection::class, $options); } } public function resetAllProjections(): void { - foreach ($this->projectionClassNamesAndAliases() as $classNamesAndAlias) { - $this->contentRepository->resetProjectionState($classNamesAndAlias['className']); - } + $this->projections->resetAll(); } public function highestSequenceNumber(): SequenceNumber @@ -67,15 +65,15 @@ public function numberOfProjections(): int } /** - * @return class-string> + * @return ProjectionInterface */ - private function resolveProjectionClassName(string $projectionAliasOrClassName): string + private function resolveProjection(string $projectionAliasOrClassName): ProjectionInterface { $lowerCaseProjectionName = strtolower($projectionAliasOrClassName); $projectionClassNamesAndAliases = $this->projectionClassNamesAndAliases(); foreach ($projectionClassNamesAndAliases as $classNamesAndAlias) { if (strtolower($classNamesAndAlias['className']) === $lowerCaseProjectionName || strtolower($classNamesAndAlias['alias']) === $lowerCaseProjectionName) { - return $classNamesAndAlias['className']; + return $this->projections->get($classNamesAndAlias['className']); } } throw new \InvalidArgumentException(sprintf( diff --git a/Neos.ContentRepository.Core/Classes/Service/ProjectionServiceFactory.php b/Neos.ContentRepository.Core/Classes/Service/ProjectionServiceFactory.php new file mode 100644 index 00000000000..337bd1df442 --- /dev/null +++ b/Neos.ContentRepository.Core/Classes/Service/ProjectionServiceFactory.php @@ -0,0 +1,24 @@ + + * @api + */ +class ProjectionServiceFactory implements ContentRepositoryServiceFactoryInterface +{ + public function build(ContentRepositoryServiceFactoryDependencies $serviceFactoryDependencies): ProjectionService + { + return new ProjectionService( + $serviceFactoryDependencies->projections, + $serviceFactoryDependencies->contentRepository, + $serviceFactoryDependencies->eventStore, + ); + } +} diff --git a/Neos.ContentRepository.LegacyNodeMigration/Classes/Command/CrCommandController.php b/Neos.ContentRepository.LegacyNodeMigration/Classes/Command/CrCommandController.php index 337a3aa66ce..c433cae6d18 100644 --- a/Neos.ContentRepository.LegacyNodeMigration/Classes/Command/CrCommandController.php +++ b/Neos.ContentRepository.LegacyNodeMigration/Classes/Command/CrCommandController.php @@ -19,12 +19,12 @@ use Doctrine\DBAL\Exception as DBALException; use Doctrine\DBAL\Exception\ConnectionException; use Neos\ContentRepository\Core\Projection\CatchUpOptions; +use Neos\ContentRepository\Core\Service\ProjectionServiceFactory; use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId; use Neos\ContentRepository\LegacyNodeMigration\LegacyMigrationService; use Neos\ContentRepository\LegacyNodeMigration\LegacyMigrationServiceFactory; use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry; use Neos\ContentRepositoryRegistry\Factory\EventStore\DoctrineEventStoreFactory; -use Neos\ContentRepositoryRegistry\Service\ProjectionReplayServiceFactory; use Neos\Flow\Cli\CommandController; use Neos\Flow\Persistence\PersistenceManagerInterface; use Neos\Flow\Property\PropertyMapper; @@ -47,7 +47,7 @@ public function __construct( private readonly PropertyMapper $propertyMapper, private readonly ContentRepositoryRegistry $contentRepositoryRegistry, private readonly SiteRepository $siteRepository, - private readonly ProjectionReplayServiceFactory $projectionReplayServiceFactory, + private readonly ProjectionServiceFactory $projectionServiceFactory, ) { parent::__construct(); } @@ -120,7 +120,7 @@ public function migrateLegacyDataCommand(bool $verbose = false, string $config = } $this->connection->executeStatement('TRUNCATE ' . $connection->quoteIdentifier($eventTableName)); // we also need to reset the projections; in order to ensure the system runs deterministically - $projectionService = $this->contentRepositoryRegistry->buildService($contentRepositoryId, $this->projectionReplayServiceFactory); + $projectionService = $this->contentRepositoryRegistry->buildService($contentRepositoryId, $this->projectionServiceFactory); $projectionService->resetAllProjections(); $this->outputLine('Truncated events'); diff --git a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php index 1dbe5f71716..7ddcc465794 100644 --- a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php +++ b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php @@ -27,6 +27,9 @@ use Neos\ContentRepository\Core\Projection\ContentGraph\VisibilityConstraints; use Neos\ContentRepository\Core\Service\ContentStreamPruner; use Neos\ContentRepository\Core\Service\ContentStreamPrunerFactory; +use Neos\ContentRepository\Core\Service\ProjectionService; +use Neos\ContentRepository\Core\Service\ProjectionServiceFactory; +use Neos\ContentRepository\Core\SharedModel\Exception\RootNodeAggregateDoesNotExist; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId; use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId; use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamState; @@ -279,8 +282,9 @@ abstract protected function getContentRepositoryService( */ public function iReplayTheProjection(string $projectionName): void { - $this->currentContentRepository->resetProjectionState($projectionName); - $this->currentContentRepository->catchUpProjection($projectionName, CatchUpOptions::create()); + /** @var ProjectionService $projectionService */ + $projectionService = $this->contentRepositoryRegistry->buildService($this->currentContentRepository->id, $this->getObject(ProjectionServiceFactory::class)); + $projectionService->replayProjection($projectionName, CatchUpOptions::create()); } protected function deserializeProperties(array $properties): PropertyValuesToWrite diff --git a/Neos.ContentRepositoryRegistry.TestSuite/Classes/Behavior/CRRegistrySubjectProvider.php b/Neos.ContentRepositoryRegistry.TestSuite/Classes/Behavior/CRRegistrySubjectProvider.php index c026f755119..611319cf0eb 100644 --- a/Neos.ContentRepositoryRegistry.TestSuite/Classes/Behavior/CRRegistrySubjectProvider.php +++ b/Neos.ContentRepositoryRegistry.TestSuite/Classes/Behavior/CRRegistrySubjectProvider.php @@ -17,6 +17,8 @@ use Neos\ContentRepository\Core\ContentRepository; use Neos\ContentRepository\Core\Factory\ContentRepositoryServiceFactoryInterface; use Neos\ContentRepository\Core\Factory\ContentRepositoryServiceInterface; +use Neos\ContentRepository\Core\Service\ProjectionService; +use Neos\ContentRepository\Core\Service\ProjectionServiceFactory; use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId; use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry; use Neos\ContentRepositoryRegistry\Exception\ContentRepositoryNotFoundException; @@ -66,7 +68,9 @@ public function iInitializeContentRepository(string $contentRepositoryId): void $contentRepository->setUp(); self::$alreadySetUpContentRepositories[] = $contentRepository->id; } - $contentRepository->resetProjectionStates(); + /** @var ProjectionService $projectionService */ + $projectionService = $this->contentRepositoryRegistry->buildService($contentRepository->id, $this->getObject(ProjectionServiceFactory::class)); + $projectionService->resetAllProjections(); } /** diff --git a/Neos.ContentRepositoryRegistry/Classes/Command/CrCommandController.php b/Neos.ContentRepositoryRegistry/Classes/Command/CrCommandController.php index bbbbd040254..af3b60a8521 100644 --- a/Neos.ContentRepositoryRegistry/Classes/Command/CrCommandController.php +++ b/Neos.ContentRepositoryRegistry/Classes/Command/CrCommandController.php @@ -6,10 +6,10 @@ use Neos\ContentRepository\Core\Projection\CatchUpOptions; use Neos\ContentRepository\Core\Projection\ProjectionStatusType; use Neos\ContentRepository\Core\Service\ContentStreamPrunerFactory; +use Neos\ContentRepository\Core\Service\ProjectionServiceFactory; use Neos\ContentRepository\Core\Service\WorkspaceMaintenanceServiceFactory; use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId; use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry; -use Neos\ContentRepositoryRegistry\Service\ProjectionReplayServiceFactory; use Neos\EventStore\Model\Event\SequenceNumber; use Neos\EventStore\Model\EventStore\StatusType; use Neos\Flow\Cli\CommandController; @@ -22,7 +22,7 @@ final class CrCommandController extends CommandController public function __construct( private readonly ContentRepositoryRegistry $contentRepositoryRegistry, - private readonly ProjectionReplayServiceFactory $projectionServiceFactory, + private readonly ProjectionServiceFactory $projectionServiceFactory, ) { parent::__construct(); } diff --git a/Neos.ContentRepositoryRegistry/Classes/Service/ProjectionReplayServiceFactory.php b/Neos.ContentRepositoryRegistry/Classes/Service/ProjectionReplayServiceFactory.php deleted file mode 100644 index 337297d9bb6..00000000000 --- a/Neos.ContentRepositoryRegistry/Classes/Service/ProjectionReplayServiceFactory.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @internal this is currently only used by the {@see CrCommandController} - */ -#[Flow\Scope("singleton")] -final class ProjectionReplayServiceFactory implements ContentRepositoryServiceFactoryInterface -{ - - public function build(ContentRepositoryServiceFactoryDependencies $serviceFactoryDependencies): ContentRepositoryServiceInterface - { - return new ProjectionReplayService( - $serviceFactoryDependencies->projections, - $serviceFactoryDependencies->contentRepository, - $serviceFactoryDependencies->eventStore, - ); - } -} diff --git a/Neos.Neos/Classes/Command/CrCommandController.php b/Neos.Neos/Classes/Command/CrCommandController.php index e7e70822eb3..cb43bfb4ef8 100644 --- a/Neos.Neos/Classes/Command/CrCommandController.php +++ b/Neos.Neos/Classes/Command/CrCommandController.php @@ -7,6 +7,7 @@ use League\Flysystem\Filesystem; use League\Flysystem\Local\LocalFilesystemAdapter; use Neos\ContentRepository\Core\Projection\CatchUpOptions; +use Neos\ContentRepository\Core\Service\ProjectionServiceFactory; use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId; use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId; use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; @@ -15,7 +16,6 @@ use Neos\ContentRepository\Export\ImportService; use Neos\ContentRepository\Export\ImportServiceFactory; use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry; -use Neos\ContentRepositoryRegistry\Service\ProjectionReplayServiceFactory; use Neos\Flow\Annotations as Flow; use Neos\Flow\Cli\CommandController; use Neos\Flow\Persistence\PersistenceManagerInterface; @@ -42,7 +42,7 @@ public function __construct( private readonly ResourceManager $resourceManager, private readonly PersistenceManagerInterface $persistenceManager, private readonly ContentRepositoryRegistry $contentRepositoryRegistry, - private readonly ProjectionReplayServiceFactory $projectionReplayServiceFactory, + private readonly ProjectionServiceFactory $projectionServiceFactory, private readonly AssetUsageService $assetUsageService, private readonly WorkspaceService $workspaceService, ) { @@ -116,7 +116,7 @@ public function importCommand(string $path, string $contentRepository = 'default $this->outputLine('Replaying projections'); - $projectionService = $this->contentRepositoryRegistry->buildService($contentRepositoryId, $this->projectionReplayServiceFactory); + $projectionService = $this->contentRepositoryRegistry->buildService($contentRepositoryId, $this->projectionServiceFactory); $projectionService->replayAllProjections(CatchUpOptions::create()); $this->outputLine('Assigning live workspace role'); diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index ebbd2ba29a9..f8396255b0a 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1,9 +1,5 @@ parameters: ignoreErrors: - - - message: "#^The internal method \"Neos\\\\ContentRepository\\\\Core\\\\Projection\\\\Projections\\:\\:getClassNames\" is called\\.$#" - count: 1 - path: Neos.ContentRepositoryRegistry/Classes/Service/ProjectionReplayService.php - message: "#^Method Neos\\\\Neos\\\\Controller\\\\Backend\\\\MenuHelper\\:\\:buildModuleList\\(\\) return type has no value type specified in iterable type array\\.$#"