What pattern to make app believe it is not "live" when replaying events

164 views
Skip to first unread message

Nathan Evans

unread,
Aug 1, 2012, 4:21:27 AM8/1/12
to ddd...@googlegroups.com
What if you have an event that say sends an e-mail. App shuts down. App starts up and recreates its state by replaying events. When it gets to the event that results in an e-mail being sent out, then it will get sent out for a second time.

I can think of several ways around this but they all seem leaky. In the sense that it means the app will have to start checking whether it is "live" or just "replaying/projecting". This would mean that the domain model is at least slightly aware of its persistence mechanism which doesn't seem right.

Any ideas? :)

Greg Young

unread,
Aug 1, 2012, 4:29:32 AM8/1/12
to ddd...@googlegroups.com
Projections should never do behaviours.
--
Le doute n'est pas une condition agréable, mais la certitude est absurde.

Nathan Evans

unread,
Aug 1, 2012, 5:03:11 AM8/1/12
to ddd...@googlegroups.com
Yeah I realise that, otherwise you'll get the problem of duplicate e-mails being sent out, duplicate web service calls, etc etc.

So what is the elegant solution?

Maybe this is more of a DDD question than anything. Is it simply that the domain model should purely be focused upon managing its own state and logic, rather than performing behaviours outside of its concern?

Thanks.

On Wednesday, August 1, 2012 9:29:32 AM UTC+1, Greg Young wrote:
Projections should never do behaviours.

Adam Dymitruk

unread,
Aug 1, 2012, 5:05:56 AM8/1/12
to ddd...@googlegroups.com

Your email service should be resilient to duplicate messages for one. But you have a bigger issue. You don't do anything except set state when hydrating.

Greg Young

unread,
Aug 1, 2012, 5:07:35 AM8/1/12
to ddd...@googlegroups.com
The sending of the email sounds like it would be something that
happens as part of a long running workflow.

Nathan Evans

unread,
Aug 1, 2012, 5:16:54 AM8/1/12
to ddd...@googlegroups.com
It's purely a theoretical question. This isn't an actual project I'm working on.

So I guess the answer is either one of the following:

1. Don't ever actually send that e-mail from a domain event. Do it somewhere else, such as the layer where the domain event was raised in the first place.

2. Continue sending that e-mail from a domain event. But wrap it in a condition like: if (projecting == false) { /* send e-mail */ }

Which is it? :)


On Wednesday, August 1, 2012 10:05:56 AM UTC+1, Adam Dymitruk wrote:

Your email service should be resilient to duplicate messages for one. But you have a bigger issue. You don't do anything except set state when hydrating.

Adam Dymitruk

unread,
Aug 1, 2012, 5:31:19 AM8/1/12
to ddd...@googlegroups.com

The answer is not one of these.

Nathan Evans

unread,
Aug 1, 2012, 6:05:32 AM8/1/12
to ddd...@googlegroups.com
Seems I was right though:  http://lostechies.com/jimmybogard/2008/08/21/services-in-domain-driven-design/ 

This was what I was thinking all along really but just wanted to be sure.

Perhaps I was having a blonde moment, sure. But I'm only on day 3 of recovery from having my brain implosion when I first learnt of Event Sourcing :)


On Wednesday, August 1, 2012 10:31:19 AM UTC+1, Adam Dymitruk wrote:

The answer is not one of these.

Greg Young

unread,
Aug 1, 2012, 6:12:18 AM8/1/12
to ddd...@googlegroups.com
Yes n infrastructure service can be used for this...

A question to ask yourself though. If its temporarily failing should
we reject the transaction? There are times when the answer to this
question is a yes but more often than not its a no. If I can't send an
email right now to confirm your order should I not accept your order?

Greg

Nathan Evans

unread,
Aug 1, 2012, 6:27:23 AM8/1/12
to ddd...@googlegroups.com
That's an implementation detail more than anything, surely? And one that is normally resolved with a service bus, or at least by queuing up the e-mail somewhere.


On Wednesday, August 1, 2012 11:12:18 AM UTC+1, Greg Young wrote:
Yes n infrastructure service can be used for this...

A question to ask yourself though. If its temporarily failing should
we reject the transaction? There are times when the answer to this
question is a yes but more often than not its a no. If I can't send an
email right now to confirm your order should I not accept your order?

Greg

Greg Young

unread,
Aug 1, 2012, 6:43:27 AM8/1/12
to ddd...@googlegroups.com
I am giving a generalized answer (its not always just email). What
about charging a credit card, writing a transaction to the accounting
system, or telling inventory to move the item to shipping ....

There are loads of cases where you don't want it done as part of the
transaction for the command but prefer to do it from an event (but not
in a projection). This is where long running workflows (process
managers/sagas/whatever you want to call them) come in.

Greg

Nathan Evans

unread,
Aug 1, 2012, 6:52:24 AM8/1/12
to ddd...@googlegroups.com
How can it be done in an event but not in a projection? That was my original wonder. It sounds like you are saying that this, in certain cases, is a totally valid design? So what is the best pattern for having that event exist, but making it act like a "null event" whenever it is replayed via projection?


On Wednesday, August 1, 2012 11:43:27 AM UTC+1, Greg Young wrote:
I am giving a generalized answer (its not always just email). What
about charging a credit card, writing a transaction to the accounting
system, or telling inventory to move the item to shipping ....

There are loads of cases where you don't want it done as part of the
transaction for the command but prefer to do it from an event (but not
in a projection). This is where long running workflows (process
managers/sagas/whatever you want to call them) come in.

Greg

Greg Young

unread,
Aug 1, 2012, 6:53:57 AM8/1/12
to ddd...@googlegroups.com
I say the pattern names in my response:

"There are loads of cases where you don't want it done as part of the
transaction for the command but prefer to do it from an event (but not
in a projection). This is where long running workflows (process
managers/sagas/whatever you want to call them) come in."

Dennis Traub

unread,
Aug 1, 2012, 7:14:44 AM8/1/12
to ddd...@googlegroups.com
There are different types of event handlers. Not every event handler is a projection.
Reply all
Reply to author
Forward
0 new messages