Live data from Hacker News

Event Sourcing is Hard

chriskiehl.com

151–160 of 166 posts

Re: Event Sourcing is Hard

#151

Event Sourcing = everything that happens is an event. Save all the events and you can always get to the latest state, as well as what things look like at any time in the past. What an "event" is depends on your business domain and the granularity of processing. It's very common in enterprise apps with complex workflows (like payment processing or manufacturing). Good fit for functional programming techniques and make…

What about when event structures change? Now you’re having to push versions into your events and keeping every version of your serialisation format. Redux often does not have to keep track of versions, because the event stream is consistent for that session.

I have actually written a book on this.

Its not that hard to deal with. Dealing with it through ad-hoc "we will come up with something as we go along" can be a bit of a pain though. It is in fact fairly trivial to handle if some thought is put into it.

Re: Event Sourcing is Hard

#152
post #116

Earlier quoted context omitted.

I might be misinterpreting your example, but wouldn't you have both the auth service and the preferences service listening for a 'new user' event (which would contain all the details needed by both systems), and both if them acting on it? Of course it would get more complex to handle error conditions, e.g what do you do if there is validation on the preferences that fails...

There are commands and events in CQRS/ES - where you need commands and success reported from multiple subsystems from front end interaction, now you need a transaction coordinator for your “saga” Typically the front end needed to get a success message to say user created, or user creation rejected (e.g. backend checking on valid postcode, valid username, etc - rejections which would come from two separate services.)

I am completely confused by your description ...

I have also not used a 2pc transaction coordinator in well over a decade.

Also you use the term "saga" which is correct in that what people are often doing here is not in fact a saga (which actually has a pattern description) it is usually a process manager which is a different pattern.

Re: Event Sourcing is Hard

#153

Earlier quoted context omitted.

> LMAX's in-memory structures are persistent across input events, so if there is an error it's important to not leave that memory in an inconsistent state. However there's no automated rollback facility. As a consequence the LMAX team puts a lot of attention into ensuring the input events are fully valid before doing any mutation of the in-memory persistent state. They have found that testing is a key tool in flushin…

Not quite! I don't think that's what they're getting at. The idea is this: Say you have a record A with fields f1, f2, f3. When an even comes in you run a function F with steps s1, s2, s3 each of which may modify a field of record A. Here's the issue, if s3 fails (due to "invalid input"), the modifications to A from s1 and s2 are incorrect and A is now corrupt. There are a bunch of ways to handle this but the one des…

> until you're at a stage where nothing can fail anymore.

... and then there's a NullPointerException because you forgot to check something that could indeed fail (i.e.: you have a bug).

In other words: they advise you to not have bugs in that part of the codebase, which was precisely my objection.

Re: Event Sourcing is Hard

#154

Earlier quoted context omitted.

Not quite! I don't think that's what they're getting at. The idea is this: Say you have a record A with fields f1, f2, f3. When an even comes in you run a function F with steps s1, s2, s3 each of which may modify a field of record A. Here's the issue, if s3 fails (due to "invalid input"), the modifications to A from s1 and s2 are incorrect and A is now corrupt. There are a bunch of ways to handle this but the one des…

> until you're at a stage where nothing can fail anymore. ... and then there's a NullPointerException because you forgot to check something that could indeed fail (i.e.: you have a bug). In other words: they advise you to not have bugs in that part of the codebase, which was precisely my objection.

Absolutely. But doing things in this style protect you from large classes of the especially hard to reproduce bugs. Nothings perfect but it helps a lot!

I'd never heard it articulated before but I personally discovered this style over the years as well.

Re: Event Sourcing is Hard

#155

I agree with the author completely. I worked on a fairly large system using event sourcing, it was a never-ending nightmare. Maybe with better tooling someday it will be usable, but not now. Events are pretty much a database commit log. This is extremely space innefficient to keep around. And not nearly use useful as you might think. Re-runs need to happen pretty often as you change how events are handled. Even in ou…

The replays are done on the processor right ? Isn't it supposed to be fast ?

Re: Event Sourcing is Hard

#156
post #152
post #116

Earlier quoted context omitted.

There are commands and events in CQRS/ES - where you need commands and success reported from multiple subsystems from front end interaction, now you need a transaction coordinator for your “saga” Typically the front end needed to get a success message to say user created, or user creation rejected (e.g. backend checking on valid postcode, valid username, etc - rejections which would come from two separate services.)

I am completely confused by your description ... I have also not used a 2pc transaction coordinator in well over a decade. Also you use the term "saga" which is correct in that what people are often doing here is not in fact a saga (which actually has a pattern description) it is usually a process manager which is a different pattern.

If you’re confused, welcome to how everyone felt. The nuances and abstract definitions made for confusion for the staff. I’ve forgotten what I knew about it, you may well be right in your definitions, however what was clear was that we needed to implement asynchronous pub/sub comms on the Kafka queue to get this work. What might have been simple with an RPC (e.g. a POST/PUT) was turned into a system which needed to track the state of its asynchronous RPCs, and listen to the queue for responses.

All of this was for no real purpose, and as I said the proof was in the pudding - tens of millions of dollars wasted, hundreds of staff hired and then fired. The domain itself was not complex (e-commerce) but the implementation was ludicrous.

There were basic delivery problems in the project as there was a complete lack of keeping things simple, and massive overengineering.

Re: Event Sourcing is Hard

#157
post #151

Earlier quoted context omitted.

What about when event structures change? Now you’re having to push versions into your events and keeping every version of your serialisation format. Redux often does not have to keep track of versions, because the event stream is consistent for that session.

I have actually written a book on this. Its not that hard to deal with. Dealing with it through ad-hoc "we will come up with something as we go along" can be a bit of a pain though. It is in fact fairly trivial to handle if some thought is put into it.

Any reference to the book you wrote?

Re: Event Sourcing is Hard

#158

Event Sourcing = everything that happens is an event. Save all the events and you can always get to the latest state, as well as what things look like at any time in the past. What an "event" is depends on your business domain and the granularity of processing. It's very common in enterprise apps with complex workflows (like payment processing or manufacturing). Good fit for functional programming techniques and make…

What about when event structures change? Now you’re having to push versions into your events and keeping every version of your serialisation format. Redux often does not have to keep track of versions, because the event stream is consistent for that session.

There is no easy way (in any platform as far as I'm aware), of discovering and updating all clients that depend on some data structure if you plan to change the data structure in an incompatible way.

Better to "grow" your data structures than "change" them.

Re: Event Sourcing is Hard

#159

Event Sourcing = everything that happens is an event. Save all the events and you can always get to the latest state, as well as what things look like at any time in the past. What an "event" is depends on your business domain and the granularity of processing. It's very common in enterprise apps with complex workflows (like payment processing or manufacturing). Good fit for functional programming techniques and make…

> Save all the events and you can always get to the latest state This isn't actually true and good event sourcing guides will point out why this isn't true. Event based systems are naturally racey, on a rerun of a stream of events the order in which the events is processed may change and you might therefore get a different result than the first time. For example, if you have 1 item remaining in inventory but two peop…

There is only a request, no "customer X buys the last item" event unless the system proves that the item is actually available (and other conditions). An easy way is putting requests in a queue, to ensure one of the buying attempts comes after the other and sees the item unavailable.

Re: Event Sourcing is Hard

#160
post #2

Good summary of the drawbacks of ES. I think one thing can not be repeated often enough: Eventsourcing can be an incredibly valuable approach, but almost always only for a very SMALL SUBSET of your system. Most of the problems with ES materialize from trying to build your whole architecture around it. I think many developers fall into this trap because theoretically the concept sounds so appealing and elegant (immuta…

I think calling it an architecture is a bit strong. Isn't it more like a pattern that you can use for some of the connective lines in an architecture? Reading through this, it seems a lot of the pitfalls come from neglecting the architecture whilst implementing event sourcing.

Event sourcing is an "architecture" because it can possibly be used for a part of a system, but only all-in (otherwise, you lose events you should preserve and all integrity benefits).
Post reply on HN