Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TASK: Cleanup projection catch-up trigger extensibility #5288

Conversation

mhsdesign
Copy link
Member

@mhsdesign mhsdesign commented Oct 13, 2024

Extracted from #4988

Followup for #5049

We decided to run the content repository in sync mode. This was done first via a little hack. This pr now removes the left-over interfaces of the catchup triggering and hardcodes the catchup to be fully synchronous.

Upgrade instructions

Review instructions

Checklist

  • Code follows the PSR-2 coding style
  • Tests have been created, run and adjusted as needed
  • The PR is created against the lowest maintained branch
  • Reviewer - PR Title is brief but complete and starts with FEATURE|TASK|BUGFIX
  • Reviewer - The first section explains the change briefly for change-logs
  • Reviewer - Breaking Changes are marked with !!! and have upgrade-instructions

* @return CommandResult
* @throws ConcurrencyException in case the expectedVersion does not match
*/
public function publishEvents(EventsToPublish $eventsToPublish): CommandResult
public function publishEvents(EventsToPublish $eventsToPublish, ContentRepository $contentRepository): CommandResult
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

having to pass the full cr along here seems wrong but is the only way if the EventPersister wants to be a separate class and not inlined in the ContentRepository

Previously the dependency problem was not really visible as we used the contentRepositoryRegistry to get the content repository in a ProjectionCatchUpTriggerInterface but there was no dependency flow set up then as well.

@mhsdesign mhsdesign force-pushed the task/cleanup-ProjectionCatchUpTrigger-extensibility branch from c256b63 to ac22547 Compare October 14, 2024 19:43
@mhsdesign mhsdesign changed the title TASK: cleanup projection catch up trigger extensibility TASK: Cleanup projection catch up trigger extensibility Oct 14, 2024
@mhsdesign mhsdesign changed the title TASK: Cleanup projection catch up trigger extensibility TASK: Cleanup projection catch-up trigger extensibility Oct 14, 2024
@mhsdesign mhsdesign marked this pull request as ready for review October 14, 2024 19:45
@mhsdesign mhsdesign force-pushed the task/cleanup-ProjectionCatchUpTrigger-extensibility branch from ac22547 to ddac2c4 Compare October 14, 2024 19:54
Copy link
Member

@bwaidelich bwaidelich left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 by reading, thanks!

}

public function handle(CommandInterface $command): CommandResult
{
return $this->contentRepository->handle($command);
}

public function publishEvents(EventsToPublish $eventsToPublish): void
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the weirdest API, why would we have this here? CommandHandlingDependencies::publishEvents makes no sense to me.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the problem is that for publishing events we need a catchup afterwards and the catchup hook extensibility require the content repository to be build.

The CommandHandlingDependencies are a purely internal thing and the handle() method on it already is a code smell due to the workspace command handler "doing to much" besides just publishing events for one command as we issue sub commands in the middle of handling another command.

For publishing an event stream, we need low level access to publish all events which was previously done via $this->eventPersister->publishEvents($events).
This leveraged the odd dependency flow of refetching the content repository from the Neos registry (see comment above) but now we need to pass the content repository for the said reasons explicitly.

Instead of exposing the content repository from $commandHandlingDependencies and using it like $this->eventPersister->publishEvents($events, $commandHandlingDependencies->contentRepository) i propose to keep the contentRepository instance private and introduce the new method: $commandHandlingDependencies->publishEvents($events)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather expose the CR here instead of adding this method, but maybe an abstraction around projection catchup is not bad, I do like the current api better than what happens in this change.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we discussed having a factory like so, but the catchup logic is still placed ON the content repository and we would have to move the codeblock to the event persister ...

final readonly class CatchUpHookFactoryBuilder
{
    public function __construct(
        private ContentRepository $contentRepository
    ) {
    }

    public function build(CatchUpHookFactoryInterface $catchUpHookFactory): CatchUpHookInterface
    {
        return $catchUpHookFactory->build($this->contentRepository);
    }
}

Also introducing a read site content repository or just passing the content repository read model to the catchup hooks would certainly be promising as it would prevent recursive handling via handle but nothing for now.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

haha @kitsunet with #5301 on the rise i guess i can revert d3119b8 as well have so much logic on the poor object that an additional method persistEvents wouldn't hurt :D

I just experimented with returning the events instead of handling them in between, which is much cleaner imo and would allow us to actually get rid of that thing :D https://neos-project.slack.com/archives/C0L41E268/p1729546247272549

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still like it better this way 😆

}
try {
return $this->eventPersister->publishEvents(
$commandHandlingDependencies->publishEvents(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so this seems to be the single use of this weird API, why don't we keep the EventPersister here?

Copy link
Member

@kitsunet kitsunet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like the persistEvents api addition, that shouldn't be there IMHO.

@mhsdesign mhsdesign requested a review from kitsunet October 20, 2024 18:44
Copy link
Member

@kitsunet kitsunet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like it like this

@mhsdesign mhsdesign merged commit 339987c into neos:9.0 Oct 22, 2024
7 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants