Rotorsoft / firebase-event-store

CQRS style Event Sourcing backend and Kafka like bus on Firebase Firestore
63 stars 2 forks source link

Handle distributed database #2

Open mdopp opened 5 years ago

mdopp commented 5 years ago

Hi, how is your solution to handle the fact, that multiple firebase instances may have a different "currentState"? I mean if you store an event in the database does not guarantee that, while reading it in another instance, you get the same result "in time". As the whole database is eventual consistent

Rotorsoft commented 5 years ago

Eventual consistency will always be an issue in any CQRS implementation but not necessarily a show stopper if you plan to deal with it. This solution will only commit events when the stored version of the given aggregate matches the expected version provided when sending commands, otherwise a concurrency error is thrown. Most applications won’t be highly concurrent at the aggregate level though.

mdopp commented 5 years ago

The problem with firebase is that it is distributed, and each insert is eventual consistent.

Example: someone in Asia is executing an command, resulting in a new event that is stored in the eventstore. Same command is executed on another db instance by another user. Due to the fact that the commit to all instances take some time, the 2nd user will be allowed to execute the command resulting in the same event. Normally, this is avoided by either run a singleton aggregate instance, or by using database level commits. With faas not allowing singleton, and a database that is eventual consistent, I do not see how to make it bullet proof.

Maybe an check function running on each insert, checking the event consistency, might work?

Rotorsoft commented 5 years ago

Events are committed inside a transaction and Firestore transactions are supposed to be ACID across regions. It would be nice if we can find official confirmation since I haven’t tested these type of scenarios and it would be a real issue if that’s not the case.

mdopp commented 5 years ago

You are right, the official documentation backs your statement.


When using transactions, note that:

Read operations must come before write operations. A function calling a transaction (transaction function) might run more than once if a concurrent edit affects a document that the transaction reads. Transaction functions should not directly modify application state. Transactions will fail when the client is offline.

I will recheck my code, cause I was trying something similar last summer. Maybe my code had some errors, or this was not supported 100% back then. Get back to you in a few days.

Anyway: cool stuff!