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

Overhaul CatchUp and CatchUpHook implementation #4289

Closed
bwaidelich opened this issue May 23, 2023 · 3 comments · Fixed by #4405
Closed

Overhaul CatchUp and CatchUpHook implementation #4289

bwaidelich opened this issue May 23, 2023 · 3 comments · Fixed by #4405
Assignees
Labels
Milestone

Comments

@bwaidelich
Copy link
Member

bwaidelich commented May 23, 2023

Currently there's a lot of duplication in the catchUp() methods of projections and support for catch up hooks has to be implemented manually (see

{
$catchUpHook = $this->catchUpHookFactory->build($contentRepository);
$catchUpHook->onBeforeCatchUp();
$catchUp = CatchUp::create(
fn(EventEnvelope $eventEnvelope) => $this->apply($eventEnvelope, $catchUpHook),
$this->checkpointStorage
);
$catchUp = $catchUp->withOnBeforeBatchCompleted(fn() => $catchUpHook->onBeforeBatchCompleted());
$catchUp->run($eventStream);
$catchUpHook->onAfterCatchUp();
}
for example).

We should probably replace

public function catchUp(EventStreamInterface $eventStream, ContentRepository $contentRepository): void

by something like

public function apply(EventInterface $event): void

in the ProjectionInterface and move the looping/catchup hook logic out.

Projections that need more control over the whole event stream could opt in with some additional interface if we need it at all.

@bwaidelich bwaidelich converted this from a draft issue May 23, 2023
@bwaidelich bwaidelich added the 9.0 label May 23, 2023
@skurfuerst
Copy link
Member

hey :) I am not fully sure about this, because that was IMHO the way it was done before (In Neos.EventSourcing) - I think we had some reasons to do it differently, or am I wrong? :) IMHO it also had to do with the EventEnvelope deserialization (which the framework knows nothing about).

All th ebest <3

@bwaidelich
Copy link
Member Author

I think we had some reasons to do it differently, or am I wrong? :)

No, you're totally right. But IMO that was the "wrong cut" because now we have a lot of duplication and – worse – inconsistencies (e.g. missing support for CatchUp Hooks).
Also, this would make #3854 and #4200 much easier to solve.

IMHO it also had to do with the EventEnvelope deserialization (which the framework knows nothing about).

The framework (as in neos/eventstore) does not, but our projection catchup does.
But, yes, that was definitely a reason for it because sometimes you don't need the deserialized event at all.
But we could maybe achieve the best of both worlds with additional interfaces, for example:

interface ProjectionInterface {
  public function reset(): void;
  public function canHandle(Event $event): bool;
  // ...
}

interface ToBeNamedInterface {
  public function apply(EventInterface $domainEvent): void;
}
interface ToBeNamedLowLevelInterface {
  public function catchUp(EventStreamInterface $eventStream): void
}

(but IMO we should first see if there are really many cases where we need the raw events – currently there are none IIRC)

@bwaidelich
Copy link
Member Author

As discussed with @skurfuerst we decided to change the interface from

interface ProjectionInterface {
    public function canHandle(Event $event): bool;
    public function catchUp(EventStreamInterface $eventStream, ContentRepository $contentRepository): void;
}

to

interface ProjectionInterface {
    public function canHandle(EventInterface $domainEvent): bool;
    public function apply(EventInterface $domainEvent): void;
}

Note: We won't need the $contentRepository parameter since we can handle the catch up hooks outside (in the CR catchup implementation), see #4309

Breaking Changes

This change would not be breaking to users of the APIs, but Implementations of custom projections are affected of course

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

2 participants