svalaskevicius / eventflow

cqrs+es in scala
45 stars 4 forks source link

derivative events from projections #20

Open svalaskevicius opened 9 years ago

svalaskevicius commented 9 years ago

projections can emit events that other projections / sagas depend on

svalaskevicius commented 8 years ago

... or can projection definition to be simplified and focus be put on composability?

svalaskevicius commented 8 years ago

I think now that projection should never emit events - aggregates and sagas should be used instead.

Will leave the ticket to discuss how to compose projections

octonato commented 8 years ago

Hi @svalaskevicius,

I agree that Projections should never emit events. I would also say, sagas neither. Only aggregates should emit events.

IMO, there is two main types of Sagas. Sagas that are run from time to time to bring the system in a consistent state and Sagas to run operations between aggregates.

In the last case, Sagas is just a variation of a Projection. You listen to events from one Aggregate and produce Commands to be sent to another Aggregate.

In Fun.CQRS projections are defined in terms of PartialFunctions and I can compose them with andThen and orElse. Return type is still a Future, but I'm planning to refactor it to F[_].

svalaskevicius commented 8 years ago

:+1: exactly what I thought as well :)

initially I created this ticket following geteventstore.com but I think staying in pure aggregate/projection/saga definition is better for now

Fristi commented 8 years ago

Projections are a scan / reduce over a F[A] where F[_] can be akka-stream Source, scala List, monix Observable etc. You could compose them by using Kleisli arrows.

octonato commented 8 years ago

In my case, what I mean by Projection is a function Event => Future[Unit]. Actually a PartialFunction[Event, Future[Unit]] that could be refactored to PartialFunction[Event, F[Unit]]. Note, I'm not talking here about Eventflow.

The Projection in my case is only the operation that receives an Event and modify something in the DB.

juanjovazquez commented 8 years ago

I'm in principle agree with @rcavalcanti and @svalaskevicius that projections and sagas should not emit events. That's in line with the principles of CQRS. However, in a context of eventual consistency like this, that is inherent in CQRS, how report when the projections were updated?. An user interface may need to know when the data is available and I cannot come up with other solution now that it's not projections emitting events reporting that data is available to be queried.

svalaskevicius commented 8 years ago

Hmm at this point I think it's good to separate domain events and UI notifications, which can be done in either pull or push manner :)

juanjovazquez commented 8 years ago

@svalaskevicius I agree with the separation of concerns that you mention. But, if you want to notify in a push style, you need to emit an event after projection somehow. OTOH, this event could be the responsibility of the application layer as opposed to the domain layer...

svalaskevicius commented 8 years ago

Hmm so for this purpose we could add a notification param for a projection, that is pinged when projection processes some data.

App layer can then use this to update clients.

Is this what you meant?

juanjovazquez commented 8 years ago

@svalaskevicius It could be a notification param or even some kind of listener or callback function that the application layer can subscribe to. We need to take into account that typically the application layer might be interested not in only one but in several projections at the same time maybe belonging to several domains.

So, the ability to reason about what projections we are interested in a particular moment it has to rely necessarily on the application layer or on some CEP engine, or whatever, but not on the domain itself.

Anyway, IMHO the projection shouldn't be aware of what its data is going to be used for but should provide a mechanism to enable others to be aware of its update cycle.

svalaskevicius commented 8 years ago

Yepp. Agreed :)