Eventually Consistent: How to Make a Mobile-First Distributed System
realm.io
realm.io
The CAP theorem states that in the event of a network-partition you have to choose one of C or A. More intuitively, any delay between nodes can be modeled as a temporary network partition and in that event you have but two choices either wait to return the latest data at a peer node (C) or return the last available data at a peer node (A).
Edit: Switched C and A
I'm motherf*ing amazzzzzed!!!!!!!
Having the flexibility to use the exact combination of data types that fits your specific requirements and allows you to express your intent in a way that makes it clear how you want the conflicts resolved is essential to make it work.
You can find a bit more info about our approach to conflict resolution here: https://realm.io/docs/realm-object-server/#conflict-resoluti...
Timestamps are only used to merge conflicting but causally unrelated changes. In principle we could pick a random number instead of using the timestamp and we would still achieve convergence, but it just so happens that the current local time on the device is highly correlated with the user's experience of real time, so that if the user makes conflicting changes on two offline devices, those changes will still be properly ordered in the general case.
+ for example a surprising number of computers have their local time changed to avoid license terms of poorly enforced proprietary software.
So people either rely on an OT implementation that is generic enough for their needs, or risk inconsistency or subtle bugs to chase after for years.
Other approaches such as CRDT or total order are not vulnerable to that problem, but they have other concerns (like read performance, garbage collection, or intent preservation).
But it helps to understand the fundamental constraints - for example, that operations must be commutative. In our case, we have had the luxury of designing our own database system, which means we could pick the semantics that we knew would lend themselves well to operational transformation. We have also made an effort to reuse semantics at multiple levels, limiting the number of OT instances that we had to convince ourselves would work.
Then of course, and for me at least, formal arguments are not enough, which is why we have spent a remarkable amount of resources on testing the system, including guided fuzz testing. :-)
https://www.youtube.com/watch?v=gLtO0vY_M78
https://www.youtube.com/watch?v=Jw1iFr4v58M
And now I hope my understanding is correct:
The way I see it, the most important thing to understand first is what the word partition means in the context of distributed systems. If the system is partitioned (being in partitioned state), that just means that some nodes can not talk to each other. There is an outage of some sort and when building distributed systems, you always have to expect that, so the P (partition-tolerant) from CAP is always there, you always have to choose it. After that, you just have to decide if you will be more C (consistent) or more A (available). If you pick C, then this means some nodes will have to wait until the system is back in connected state to get the latest state, but if you pick A, then you always get the answer, the last one the node had before it got disconnected.
From wiki, it looks like there are 3 main pillars to DS [1]:
- concurrency of components
- lack of global clock
- independent failure of components
So you need the failure tolerance part.
var puppies = realm.All<Dog>().Where(d => d.Age < 2);
The LINQ integration is appreciated. // Update and persist objects with a thread-safe transaction
realm.Write(() =>
{
realm.Add(new Dog { Name = "Rex", Age = 1 });
});
// Queries are updated in realtime
puppies.Count(); // => 1
I'm assuming that "updated in realtime" means "realm.Write is a blocking operation", correct?Adding something complex like OT on top of Realm's existing foundation would make me even less likely to use it in the future.
That said, it's nice to see them tackling the problem and I wish them the best. Obviously, bugs can be fixed given enough time and effort and in principle, I like their product.
Obviously one of the main points of building the new sync solution (or any library really) is to give you much more time for building differentiating features rather than building basics yourself. Now granted there are other solutions for the pure local persistence, but not many - if any - that will do what the new Realm Mobile Platform will for solving sync.
But obviously the basics must be right and solid - so hope you will provide us with sufficient info so we can get any of your issues resolved.
https://www.usenix.org/conference/osdi16/technical-sessions/...
One huge difference is that Parse is no longer developed by a company after Facebook abandoned it. It's been open sourced and its future is up to the community.
Another is very related to this article. Realm resolves all your conflicts automatically, the developer doesn't have to do that. That's even done more fine grained at the property level.
Realms focus on being an offline first database means that your data is always available locally.
Then there are subjective differences. Until the launch of the Realm Mobile Platform, Realm has not had a solution for syncing to a backend. We have a lot of users who have chosen to use Realm locally and Parse as the backend. I guess that's a testament to the local database features from Realm. But with the new syncing solution, that's no longer needed, and all the networking code can be forgotten.
I'm sure others can come up with pros for Parse, but if you are not already invested in Parse, I think most would recommend looking elsewhere due to the first point.