Fork me on GitHub
#off-topic
<
2015-10-24
>
colin.yates11:10:48

having a bad day - am I the only one who swings between ‘yeah, I’ve got this down’ and ‘wow - what was I thinking?’ simple_smile

ericlavigne13:10:34

@colin.yates: Yeah, I recognize that cycle. Usually means it's time to split that task into smaller pieces. 😉 http://www.agileforall.com/splitting-user-stories/

colin.yates13:10:35

@ericlavigne: It was more a reaction to coding/tooling in particular rather than a given use-case simple_smile

ericlavigne13:10:01

Yup, when asking team to create one new thing, we split up into many individually digestible use cases. When learning something new, we try to swallow the whole watermelon at once. I think the same solution works for both problems.

ericlavigne13:10:25

And yes, I often make the same mistake, which is why I recognize your cycle. 😉

ericlavigne13:10:09

@colin.yates: I'm studying event sourcing at the moment, and it looks like you're ahead of me. Any tools you recommend for the storage/replay/query pipeline?

colin.yates13:10:22

not really - I store the event log in an append only format in a SQL table (for non-functional reasons).

colin.yates13:10:05

I then have a bunch of listeners which react to an event, hydrate the relevant entity from the event log and denormalise into their own structures

colin.yates13:10:19

each one is a (Stuart Sierra) component

colin.yates13:10:39

but I couldn’t find any decent prior art so it is all hand rolled

colin.yates13:10:59

I would love to open source it but the great thing is that there is hardly anything to the infrastructure/glue code

colin.yates13:10:30

were I to do it again I might utilise core async and use a document database but it is all trivially simple stuff simple_smile

ericlavigne13:10:42

Best prior art I found was https://geteventstore.com/ but it is very incomplete.

colin.yates13:10:26

That’s the one from Greg? He is definitely a guy I would listen to. But yes, I looked at that but it didn’t quite fit my workflow

ericlavigne13:10:34

Sounds like you are collecting events and interpreting them at the moment that you need to query. Sounds like an approach that would only work for very little data.

colin.yates13:10:04

nope, I was processing the events when they happened (asynchronously) and updating denormalised read stores

jaen13:10:00

@ericlavigne: That's what state snapshots are for, I think. You can snapshot the entity state at some point and then read a snapshot and query only later events when need to rehydrate.

colin.yates13:10:41

having gone through this experience I can’t imagine not using an event-based approach for anything other than trivially simple CRUD type apps. Even then… simple_smile

colin.yates13:10:21

but, for me at least, it really did require a shift in mental aptitude when thinking about the solution space. I also pulled in DDD at the same time which was a mistake on hindsight

colin.yates13:10:48

all the good stuff of ‘time travel’ people are experiencing with Om and Reagent - imagine that for the whole application simple_smile

ericlavigne13:10:02

I haven't read DDD but the discussion on event sourcing does tend to mix with that.

jaen13:10:03

Hmm, why do you think DDD was a mistake?

jaen13:10:13

I kind of got impression it would fit quite well

ericlavigne13:10:33

So your event store is a single table with thrift-serialized events?

colin.yates13:10:44

so you know how everybody says “I do OO” but they don’t - from what I see (and experienced myself) that applies even more to DDD.

colin.yates13:10:54

DDD isn’t a technical discipline it is a domain modelling discipline

ericlavigne13:10:58

And you have another table tracking how far into the event stream you have processed so far?

colin.yates14:10:32

@ericlavigne: how far each component has processed so far yes. It is great because if my view changes, simply destroy its schema and reset it back to 0

colin.yates14:10:46

then it replays all those lovely events to create the updated view

colin.yates14:10:20

@jaen - they are a match made in heaven. I hadn’t anticipated though how much a proper DDD approach differs from the stuff I had been doing for 20-odd years simple_smile

colin.yates14:10:40

thinking about it, there is a lot of symmetry between micro-services and event-handlers

colin.yates14:10:49

when this insane deadline I am under passes I mean to put some effort into a set of blog posts because there is so much sympathy between FP and event sourcing - a lot of it is just good common sense.

jaen14:10:55

Ok, that is a point, when I tried to get how to DDD it was so different than what people usually do I was kinda stumped hot to tackle that.

jaen14:10:19

Yeah, I couldn't understand ES/CQRS when reading about it on some OO-oriented (that's double the oriented xD) websites, describing them in terms of objects and whatnot

jaen14:10:29

Until I read that current state is a left fold of events

jaen14:10:33

And it just clicked

colin.yates14:10:41

yes - exactly

colin.yates14:10:09

however, the complexity (for me at least) of DDD is what events and exactly how to define the aggregate roots

colin.yates14:10:25

you can get all the benefit of event sourcing without DDD by simply storing all state changes as an explicit event.

colin.yates14:10:54

then the entity is literally just a (apply merge (event-store/load ar-id)

ericlavigne14:10:54

And most of the challenge in schema design is trying to future-proof for new types of data you might need to store in the future without creating denormalization issues. But with event sourcing most of that is in views and you can always just create more.

colin.yates14:10:09

there are downsides though.

colin.yates14:10:29

you don’t realise exactly how many business decisions are made in queries until you manually capture each decision in an event!

colin.yates14:10:55

but performance is just blindingly fast because you literally can have one view per ‘widget’ on you UI optimised just for that.

ericlavigne14:10:59

But putting an "aggregate ID" in the event implies that you already know what views you will use it for. Aggregates are your views, right?

colin.yates14:10:27

no, aggregates is what is needed to make a decision in the domain

jaen14:10:10

It's basically a in-memory domain model, to oversimplify it a bit.

colin.yates14:10:40

so Customer and all their orders might be one aggregate (with Customer being the AR), another part of the business (i.e. another bounded context) might view the Customer as a set of delivery addresses, yet another might view that Customer as a list of purchases - each ‘Customer’ instance is the same physical real world thing and has the same ID.

colin.yates14:10:53

but each part of the app might attribute different properties to that Customer.

colin.yates14:10:37

Strictly, aggregates in DDD are silos of integrity. You define them to ensure each business decision is safely and atomically made (where possible).

colin.yates14:10:44

it really blows your mind.

jaen14:10:55

Yeah, an interesting thought just occurred to me

jaen14:10:07

Aggregates define integrity boundaries

ericlavigne14:10:24

Sounds like I need to read DDD ASAP.

jaen14:10:29

In part because of how it's rather hard to have in-memory transactions in OO

jaen14:10:40

How would the ease of doing in-memory transactions in Clojure

jaen14:10:45

Play into that

jaen14:10:10

I think that could be interesting to think about

colin.yates14:10:28

http://dddcommunity.org/book/implementing-domain-driven-design-by-vaughn-vernon/ is a great book. Eric Evans’ ‘Blue Book’ is the authority but pretty old now

colin.yates14:10:46

it also seems to have taken off much more in Microsoft land rather than Java land

jaen14:10:22

Yeah, I've been recommended Vernon as well, though that's a big thing to tackle

jaen14:10:37

IIRC ES/CQRS was actually re-invented in C# land

colin.yates14:10:49

I need to run; gotta snuggle up on the sofa with my four kids and watch ‘Penguins of Madagasca’. When I say ‘snuggle’ I mean ‘be sat on’ simple_smile

colin.yates14:10:24

well, Greg coined the CQRS term (as an extension of CQS)

jaen14:10:54

Hah; if you write something on ES/CQRS/DDD in Clojure I'll gladly read that; those are things that are better learnt from people that used it in practice

jaen14:10:56

Instead of on your own

colin.yates14:10:30

if you do want to get into DDD then I strongly suggest you go through the archives of the DDD google group - probably 9/10 messages are about “how do I do this simple thing in DDD” simple_smile.

colin.yates14:10:53

thanks @jaen - it is #1 on my TODO list once I can take a breath (current work pressure is pretty high)

colin.yates14:10:14

see you in a few hours

ericlavigne14:10:36

That is a big book but might read anyway. Really want to switch to this approach.

jaen14:10:08

If so, I'll bookmark that, it will surely come in handy at some point.