From 77778f9e2cc6c2aa0ee3560a491089465bf33f04 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Sat, 9 Nov 2024 20:56:53 +0100 Subject: [PATCH] TASK: Do not send `$commitResult` to generator but calculate expected version instead Also readd lost documentation and simplifies the `handle` The ->throw logic was initially introduced via https://github.com/neos/neos-development-collection/pull/5315 but then removed again as we thought it was no longer needed. --- .../CommandHandlerInterface.php | 3 +- .../Classes/ContentRepository.php | 15 +++++--- .../Feature/WorkspaceCommandHandler.php | 35 ++++++++++--------- 3 files changed, 30 insertions(+), 23 deletions(-) diff --git a/Neos.ContentRepository.Core/Classes/CommandHandler/CommandHandlerInterface.php b/Neos.ContentRepository.Core/Classes/CommandHandler/CommandHandlerInterface.php index 1ff7cee24eb..6e0436be8fe 100644 --- a/Neos.ContentRepository.Core/Classes/CommandHandler/CommandHandlerInterface.php +++ b/Neos.ContentRepository.Core/Classes/CommandHandler/CommandHandlerInterface.php @@ -5,14 +5,13 @@ namespace Neos\ContentRepository\Core\CommandHandler; use Neos\ContentRepository\Core\EventStore\EventsToPublish; -use Neos\EventStore\Model\EventStore\CommitResult; /** * Common interface for all Content Repository command handlers * * The {@see CommandHandlingDependencies} are available during handling to do soft-constraint checks * - * @phpstan-type YieldedEventsToPublish \Generator + * @phpstan-type YieldedEventsToPublish \Generator * @internal no public API, because commands are no extension points of the CR */ interface CommandHandlerInterface diff --git a/Neos.ContentRepository.Core/Classes/ContentRepository.php b/Neos.ContentRepository.Core/Classes/ContentRepository.php index c3277a1d4f3..45b23d1da88 100644 --- a/Neos.ContentRepository.Core/Classes/ContentRepository.php +++ b/Neos.ContentRepository.Core/Classes/ContentRepository.php @@ -110,23 +110,28 @@ public function handle(CommandInterface $command): void // control-flow aware command handling via generator try { - $yieldedEventsToPublish = $toPublish->current(); - while ($yieldedEventsToPublish !== null) { + foreach ($toPublish as $yieldedEventsToPublish) { if ($yieldedEventsToPublish->events->isEmpty()) { - $yieldedEventsToPublish = $toPublish->send(null); continue; } $eventsToPublish = $this->enrichEventsToPublishWithMetadata($yieldedEventsToPublish); try { - $commitResult = $this->eventPersister->publishWithoutCatchup($eventsToPublish); + $this->eventPersister->publishWithoutCatchup($eventsToPublish); } catch (ConcurrencyException $concurrencyException) { + // we pass the exception into the generator (->throw), so it could be try-caught and reacted upon: + // + // try { + // yield EventsToPublish(...); + // } catch (ConcurrencyException $e) { + // yield $this->reopenContentStream(); + // throw $e; + // } $yieldedErrorStrategy = $toPublish->throw($concurrencyException); if ($yieldedErrorStrategy instanceof EventsToPublish) { $this->eventPersister->publishWithoutCatchup($yieldedErrorStrategy); } throw $concurrencyException; } - $yieldedEventsToPublish = $toPublish->send($commitResult); } } finally { // We always NEED to catchup even if there was an unexpected ConcurrencyException to make sure previous commits are handled. diff --git a/Neos.ContentRepository.Core/Classes/Feature/WorkspaceCommandHandler.php b/Neos.ContentRepository.Core/Classes/Feature/WorkspaceCommandHandler.php index d1675235f85..2e9d3031ea1 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/WorkspaceCommandHandler.php +++ b/Neos.ContentRepository.Core/Classes/Feature/WorkspaceCommandHandler.php @@ -247,15 +247,17 @@ static function ($handle) use ($rebaseableCommands): void { throw WorkspaceRebaseFailed::duringPublish($commandSimulator->getCommandsThatFailed()); } + $eventsOfWorkspaceToPublish = $this->getCopiedEventsOfEventStream( + $baseWorkspace->workspaceName, + $baseWorkspace->currentContentStreamId, + $commandSimulator->eventStream(), + ); + try { - $commitResult = yield new EventsToPublish( + yield new EventsToPublish( ContentStreamEventStreamName::fromContentStreamId($baseWorkspace->currentContentStreamId) ->getEventStreamName(), - $this->getCopiedEventsOfEventStream( - $baseWorkspace->workspaceName, - $baseWorkspace->currentContentStreamId, - $commandSimulator->eventStream(), - ), + $eventsOfWorkspaceToPublish, ExpectedVersion::fromVersion($baseWorkspaceContentStreamVersion) ); } catch (ConcurrencyException $concurrencyException) { @@ -268,7 +270,7 @@ static function ($handle) use ($rebaseableCommands): void { yield $this->forkContentStream( $newContentStreamId, $baseWorkspace->currentContentStreamId, - $commitResult->highestCommittedVersion + Version::fromInteger($baseWorkspaceContentStreamVersion->value + $eventsOfWorkspaceToPublish->count()) ); yield new EventsToPublish( @@ -507,16 +509,18 @@ static function ($handle) use ($commandSimulator, $matchingCommands, $remainingC throw WorkspaceRebaseFailed::duringPublish($commandSimulator->getCommandsThatFailed()); } + // this could empty and a no-op for the rare case when a command returns empty events e.g. the node was already tagged with this subtree tag + $selectedEventsOfWorkspaceToPublish = $this->getCopiedEventsOfEventStream( + $baseWorkspace->workspaceName, + $baseWorkspace->currentContentStreamId, + $commandSimulator->eventStream()->withMaximumSequenceNumber($highestSequenceNumberForMatching), + ); + try { - // this could be a no-op for the rare case when a command returns empty events e.g. the node was already tagged with this subtree tag, meaning we actually just rebase - $commitResult = yield new EventsToPublish( + yield new EventsToPublish( ContentStreamEventStreamName::fromContentStreamId($baseWorkspace->currentContentStreamId) ->getEventStreamName(), - $this->getCopiedEventsOfEventStream( - $baseWorkspace->workspaceName, - $baseWorkspace->currentContentStreamId, - $commandSimulator->eventStream()->withMaximumSequenceNumber($highestSequenceNumberForMatching), - ), + $selectedEventsOfWorkspaceToPublish, ExpectedVersion::fromVersion($baseWorkspaceContentStreamVersion) ); } catch (ConcurrencyException $concurrencyException) { @@ -529,8 +533,7 @@ static function ($handle) use ($commandSimulator, $matchingCommands, $remainingC yield from $this->forkNewContentStreamAndApplyEvents( $command->contentStreamIdForRemainingPart, $baseWorkspace->currentContentStreamId, - // todo otherwise Features/W8-IndividualNodePublication/03-MoreBasicFeatures.feature:185 fails, see comment about emptiness above ... or should we manually count? - $commitResult?->highestCommittedVersion ?: $baseWorkspaceContentStreamVersion, + Version::fromInteger($baseWorkspaceContentStreamVersion->value + $selectedEventsOfWorkspaceToPublish->count()), new EventsToPublish( WorkspaceEventStreamName::fromWorkspaceName($command->workspaceName)->getEventStreamName(), Events::fromArray([