Dzoukr / CosmoStore

F# Event store for Azure Cosmos DB, Table Storage, Postgres, LiteDB & ServiceStack
MIT License
168 stars 21 forks source link

Comparison with Jet's Equinox #6

Open johnvanloon opened 5 years ago

johnvanloon commented 5 years ago

Didn't want to get too far off-topic in the other issue, so creating a new one to discuss this. One of the reasons it took me longer to start working on the changefeed, except for me being typical optimistic developer, is the fact a ran into this library: https://github.com/jet/equinox

Seen Jet's presentation long ago and almost no longer expected them to release this as open-source, but they did. Giving that they use this in production at their scale I think it's valuable to do a little comparison between their approach and CosmoStore.

Don't say this should be a reason to stop developing CosmoStore, but I think it's good to agree on the reason why we develop a new CosmosDb-based event-store and be explicit about that.

Dzoukr commented 5 years ago

Thanks for link, I didn't know this library (they probably opened it recently or I just missed it). From what it seems to me it is more like the platform than just single component, which is the opposite of CosmoStore. CS is event store with unified API for Cosmos DB + Azure Table Storage. Maybe I'll add more storage providers, but want to keep it simple. Not a platform, not a bunch of tools - just simple event store.

Historically I needed it for my projects, there was no ES on Cosmos, so I wrote one. Than I found pricing issue with Cosmos and wanted to easily move to Table Storage instead. So I added Table Storage support. My goal for this library is easy setup + simple API. Not aiming to be the best/widely used event store in F# world. There is no harm (actually it's good) for community to have more implementations of same/similar components.

bartelink commented 5 years ago

Hi, Apologies for not responding earlier (I only saw this yesterday)

I'm the curator of a lot of the stuff in the Equinox repo (and critically for this discussion, the author of the bulk of recent development on the CosmosDb storage impl). eta: I am not a spokesperson for Jet or Walmart and do not presently work on a Jet Platform team; this is my personal perspective on F# and/or .NET Event Sourcing libraries and frameworks.

I agree with the fundamental perspective in the OP and in the response, but would like to give some contextual info that might help other readers.

If I can say only one thing its to please not stop - the world does not need 57 of these things, but there absolutely should be way more than one.

While the term 'platform' is applied to it (there was a Platform Team around this work in Jet, and the internal systems in this space would appropriately be termed a platform - here's an overview of how that all mapped out in broad brush strokes), I'd like to give a flavor of the design philosophy of the OSS Equinox repo to assist folks in figuring out how this all juxtaposes.

Stuff only in CosmoStore 1) Sql db support via Marten (definitely conceptually fits in Equinox: see https://github.com/jet/equinox/issues/62) 2) Less code 3) more straightforward code 4) Store format requires no docs or explanation

Stuff Equinox does which I believe CosmoStore doesn't presently address: 1) folding, caching, snapshotting 2) optimized store format using CosmosDb facilities to the max 3) support for EventStore (no reason it couldnt of course) 4) validation that there are go gaps in the write sequence 5) being able to have the index be [correctly] generated during writing

The parts of Equinox that overlap with CosmoStore are: 1) the need to have a stored proc, create an indexed collection and database 2) logic to query events 3) logic to write events (inc atomic batching) 4) stuff for processing the changefeed 5) a way to do an in memory integration test

Don't say this should be a reason to stop developing CosmoStore, but I think it's good to agree on the reason why we develop a new CosmosDb-based event-store and be explicit about that.

100% - there's definitely no reason to stop. There is no one-size-fits all for Event Sourcing libraries.

There is no harm (actually it's good) for community to have more implementations of same/similar components.

I couldn't agree more. Please dont even think of stopping.

Not aiming to be the best/widely used event store in F# world.

Equinox has not been tweeted, blogged about publically or submitted to F# weekly by Jet intentionally - there was/is really only me that's realistically going to be appropriately responsive to the desires and needs of users outside of Jet in terms of Issues and PRs and/or making it a real OSS project (having said that, I and we are absolutely open to contributions). Equinox is not looking for world domination - not promoting it from the rooftops is largely in acknowledgement of the fact that we wouldn't have appropriate focus, resources or backing to do that to the max, much as I and others would hope. Jet folks (tech and non-tech) are incredibly talented, hard working, co-operative, friendly and focused but are juggling a lot of balls; Jet is a serious business with complex goals focused 100% in the domain of e-commerce.

From what it seems to me it is more like the platform than just single component, which is the opposite of CosmoStore.

While CosmoStore is clearly much more straightforward to grok and get started on, the comparison really should be with the following subset of Equinox: 1) Equinox - interfaces (but also brings in folding and optimistic retry loop) 2) Equinox.Cosmos - events, caching, snapshotting, initialization 3) Equinox.Codec - mapping DUs (optional), converting json 4) 2% of Equinox.Tool:- eqx init which provides a command-line interface to the initialization

It seems you're heading in a direction of decomposing along similar lines - this is good. I think it's important for folks to be confronted with how many things there are to consider in a real implementation. While I believe Event Sourcing produces a fundamentally simpler solution than some other approaches, nobody should be under the illusion that Event Sourcing is Easy.

CS is event store with unified API for Cosmos DB + Azure Table Storage. Maybe I'll add more storage providers, but want to keep it simple. Not a platform, not a bunch of tools - just simple event store.

Bang on; this is a really important thing to have covered for the great bulk of apps (there are teams in Jet that are only interested at this level; they arguably should be using CosmoStore over Equinox.Core.Events

Than I found pricing issue with Cosmos and wanted to easily move to Table Storage instead.

It should be noted that part of the reason that Equinox.Cosmos is more complex is that it tackles what's involved in maximizing the efficiency of CosmosDb usage head on via:

1) using point reads as much as possible; de-emphasising queries (see Storage Model in DOCUMENTATION.md) 2) caching, snapshotting

_CosmosDb has strong support for etag-contingent reads and such things; iff used with Cost Model Sympathy, it can be tremendously efficient and cost effective. While it's hard to use efficiently or cheaply, it is possible. NB this goes for absolutely all usage of CosmosDb, not just using it for Event Sourcing; arguably Event Sourcing is actually highly appropriate for CosmosDb's pricing model when done this way_

If anyone is seriously considering running at (pretty much any, you don't need to be doing thousands of requests per seconds or storing terabytes or even gigabytes) scale on CosmosDb, I'd caution about using an implementation based on queries without caching (this is not about CosmoStore - the equivalent C# impls out there that I've seen have same shortcomings in my view).

I'm happy to to/fro in this thread (especially to respond to the inevitable rebuttals of contentions of mine you find unreasonable and/or incorrect), but would also like to appeal instead for folks to join the DDD-CQRS-ES slack community - there's an invite link in the Equinox README - I can't speak highly enough of the community there. There's a #equinox room and if you make a #cosmo-store room, I'll be there and we can discuss the myriad tradeoffs in how to do all this stuff over there!

Dzoukr commented 5 years ago

Hi @bartelink,

thanks for kind words and really professional (and generous) overview - I believe if you would go deeper in code, you'd most likely found much more things to improve/fix. :) I have almost nothing to add to your comment, you described it well and can only agree.

I am not stopping to work on CosmoStore, no worries. I still love it and it gives me huge amount of learning - mostly about how hard is to write solid event store. On the other hand, it is still kind of pet project (that somehow got attention of few other F# people), so I cannot invest 40 hours of development per week to improve it. I'll keep it under the more less same pace as it has been last months. However, there are now other contributors who found it useful so it will be fun to watch how it will evolve.

Thanks again for your reaction. Jet is still the name in F# community and I use your company as reference how successful you can be using F# when talking to potential customers considering "the right .NET language". Getting feedback from Jet is kind of honor for me.

kunjee17 commented 4 years ago

@Dzoukr we should take @bartelink 's comments as part of docs. Obviously if he agrees. It is good comparison and I am pretty sure many from community will have that same questions.

bartelink commented 4 years ago

I have no objection to you doing as you see fit with my words. On occasion I transcribe Slack comments from [the DDD-CQRS-ES slack](https://github.com/ddd-cqrs-es/slack-community] with light editing and feed them as FAQs at the bottom of READMEs: https://github.com/jet/propulsion#faq, https://github.com/jet/eqinox#why-snapshots-in-stream. One issue, by @voronoipotato actually became the Equinox FAQ https://github.com/jet/equinox/issues/56 (Thanks again Alan!)

As a counterpoint though - the Equinox README is definitely on the long side, and doesnt give a place to to/fro on things (esp as some aspects are subjective) - why not just place a link in the README ?

Dzoukr commented 4 years ago

Great idea guys! @bartelink description is perfect so I added link from README as he proposed.