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

[PLATFORM-1073]: Remove projectors and policies in favour of event handlers #148

Merged

Conversation

cpiemontese
Copy link
Contributor

@cpiemontese cpiemontese commented Apr 21, 2023

https://prima-assicurazioni-spa.myjetbrains.com/youtrack/issue/PLATFORM-1073

This PR removes projectors and policies in favor of generic event handlers, which can be transactional or not

@cottinisimone cottinisimone marked this pull request as ready for review April 26, 2023 09:43
@cottinisimone cottinisimone requested a review from a team as a code owner April 26, 2023 09:43
@cpiemontese cpiemontese changed the title [PLATFORM-1073]: Streamline projectors and policies [PLATFORM-1073]: Remove projectors and policies in favour of event handlers Apr 26, 2023
Copy link
Contributor

@angelo-rendina-prima angelo-rendina-prima left a comment

Choose a reason for hiding this comment

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

Yay a new massive version bump refactor incoming downstream 🥲
Jokes aside, I see many TODOs around, is the PR actually open or is this a draft?

Comment on lines +296 to 298
// 2. the event handlers below might need to access this aggregate atomically (causing a deadlock!).
drop(aggregate_state.take_lock());

Copy link
Contributor

Choose a reason for hiding this comment

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

Have we checked there are no implications around locking, with the refactor?
I don't see anything obvious but worth double checking

Copy link
Contributor

Choose a reason for hiding this comment

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

You are right. Maybe it's worth to explicit write that in the transactional event handlers is mandatory not to call other aggregates and that are intended to be used for the read side only

@cottinisimone
Copy link
Contributor

Yay a new massive version bump refactor incoming downstream smiling_face_with_tear Jokes aside, I see many TODOs around, is the PR actually open or is this a draft?

Yes, they'll be fixed in further PRs. The work we are doing is larger than this.

Sorry for the big changes :(. I know is tedious..

/// 2. load
/// 3. lock_and_load
/// The other functions are used internally, but can be overridden if needed.
#[async_trait]
pub trait AggregateManager: Aggregate {
Copy link
Member

Choose a reason for hiding this comment

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

What about transforming this AggregateManager in something similar to the command bus of the proposal of @MatteoJoliveau, allowing to publish the produced events on the event bus after the storing of the events.
The handle_command could become something like:

  • load aggregate
  • handle command on the aggregate
  • store events
  • publish the produced events on the event bus (whatever we mean with event bus 😅)

I was thinking at this to give the idea.

Copy link
Member

Choose a reason for hiding this comment

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

Or maybe this will be covered in a following pr 🤔

Copy link
Contributor

@cottinisimone cottinisimone Apr 27, 2023

Choose a reason for hiding this comment

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

Ehi @visd0m we are doing those kind of stuff in different PRs. This is the PR related to the aggregate manager (and bounds in codebase) refactor. Wdyt? Can we discuss this changes in the other PR maybe?

Copy link
Member

Choose a reason for hiding this comment

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

Sure, sorry I didn't notice the other pr 🙏.

Copy link
Member

@visd0m visd0m left a comment

Choose a reason for hiding this comment

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

Looking forward to see other prs more focused on taking some design decision from @MatteoJoliveau proposal.

}
}

// FIXME: uncomment
Copy link
Contributor

Choose a reason for hiding this comment

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

Todo

Copy link
Contributor

Choose a reason for hiding this comment

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

You are right. This will come in further PR. We was thinking about a final PR to embellish the codebase with some ribbons

Comment on lines +8 to +12
// TODO: doc
async fn handle(&self, event: &StoreEvent<M::Event>);

// TODO: doc
async fn delete(&self, _aggregate_id: Uuid) {}
Copy link
Contributor

Choose a reason for hiding this comment

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

Docs

Copy link
Contributor

Choose a reason for hiding this comment

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

Same as above

}
}

pub trait ReplayableEventHandler<M: AggregateManager>: EventHandler<M> + Send + Sync {}
Copy link
Contributor

Choose a reason for hiding this comment

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

What's this used for?
At the very least let's have a docstring explaining what this is! I only see it used in an example

Copy link
Contributor

Choose a reason for hiding this comment

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

The idea is mostly to use in the eventually-consistent side. This marks event handlers to be replayable, that means that you can safely replay it in case of an error, or you can re-run it while rebuilding

AM: AggregateManager,
{
// TODO: doc
async fn handle(&self, event: &StoreEvent<AM::Event>, executor: &mut E) -> Result<(), AM::Error>;
Copy link
Contributor

Choose a reason for hiding this comment

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

Why does this take an executor explicitly, whereas EventHandler does not?
I assume it's to actually pass the current db transaction through?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, it's for that. TransactionalEventHandlers have been created in order to have async-transactional event handlers as projector were before this change

#[async_trait]
pub trait EventHandler<M: AggregateManager>: Send + Sync {
// TODO: doc
async fn handle(&self, event: &StoreEvent<M::Event>);
Copy link
Contributor

Choose a reason for hiding this comment

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

Unlike TransactionalEventHandler, this is infallible and does not take an executor to avoid passing an active transaction and we explicitly ignore nested errors, right?

Copy link
Contributor

Choose a reason for hiding this comment

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

Right :)

Choose a reason for hiding this comment

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

@cottinisimone re: errors, are you using the same strategy as my PoC?

In that case, I would say "we handle errors locally in the handle method", rather than "ignore". Just a semantic difference

@cpiemontese
Copy link
Contributor Author

@angelo-rendina-prima is it ok if we address some of these comments in the next PRs? do you think we can merge this PR and move forward with the next round?

@cottinisimone cottinisimone merged commit 24fcab1 into master May 3, 2023
@cottinisimone cottinisimone deleted the PLATFORM-1073/task/streamline-projectors-and-policies branch May 3, 2023 14:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants