CRDT: Conflict-free replicated data type
en.wikipedia.org
en.wikipedia.org
- Braid HTTP (https://braid.news/)
- Automerge (https://github.com/automerge/automerge)
- Gun (https://gun.eco/)
- Yjs (http://y-js.org/)
- Noms (https://github.com/attic-labs/noms)
- DAT (https://dat.foundation/)
Personally, I'm most excited for Braid's effort to bring state sync to HTTP through the IETF process, as well as Automerge's progress in P2P via Hypermerge (and it's star app, Pushpin). I'd also like to see Gun succeed, but have had a hard time getting started due to visually distracting quirks in its documentation.Cool stuff for sure.
Here’s an insightful podcast about Actual (hosted by the author of Tailwind.css), http://www.fullstackradio.com/126
BTW, Horde is a distributed supervisor, i.e. analogous to what regular Elixir OTP supervisors do, except that it can restart processes on different cluster nodes. It also provides a distributed process registry.
Daniel Azuma of Google gave a great 39 minute talk at ElixirConf 2018, "Docker and OTP: Friends or Foes?" [3], where he shows Horde (and DeltaCrdt) in action to keep a multi-player tank video game going while the Docker container it's running in gets killed and and the Elixir processes get respawned on another container. The state is persisted across Elixir nodes in other containers in an instance of DeltaCrdt.
(Again, the talk is really good -- if the above sounds interesting, you'll want to check it out [3]).
[0] https://github.com/derekkraan/delta_crdt_ex
[1] https://moosecode.nl/blog/how_deltacrdt_can_help_write_distr...
Previous HN discussion on the mini-retrospective might be interesting: https://news.ycombinator.com/item?id=19886883
A good example is inserting indentation in response to, say, the "Enter" key. In a synchronous model, this is pretty straightforward. You calculate the indentation as essentially a function of the contents of the buffer and the delta (the insert of the newline), then any other typing gets processed after that. In a CRDT model, the additional typing can be interleaved in any order, and the merge operation has to converge to the correct results. You can think about how bad that is: the user could type a hundred lines of code, complete with complex editing operations including cut and paste, deletions, undo, and then the auto-indent plugin wakes up, calculates the diff, and sends it to the core. Meanwhile, the user has typed another hundred lines, including more cut'n'pasting of the affected lines. This is perhaps unrealistic, but the CRDT model requires it. And I think it is possible to solve it (I wrote some "rope science" articles, then there was more discussion in several issues), but it's a hugely intricate puzzle compared with just applying it synchronously, and the benefit is not worth it. It's quite practical to compute indentation for any realistic source file in under a millisecond, if you've got a nice fast language.
Last release was several months ago.
GUN is running in production with 8M monthly users.
On large sites like HackerNoon and with Internet Archive.
What makes you say it is unstable?
If there is anything, please report it and we'll get it fixed.
Edit: Re grandparent: Will try to add "dark mode" to docs, in meanwhile, check out the docs on plain-text GitHub wiki ( https://github.com/amark/gun/wiki/Graph-Guide ) which is where everything pull from anyways.
I use a distributed testing tool to simulate any setup or edge cases we find, so we can fix it.
So this would be useful to replicate.
Also, a big fix was released early October.
https://doc.akka.io/docs/akka/current/typed/distributed-data...
However, as he told me a more sophisticated persistence layer is needed. Looking forward how it's emerging
It's a bit like Riak or etcd but can be used across organizational and trust boundaries similar to e.g. a cryptocurrency. Anyone can run LF as part of the same network and both data privacy and security are maintained.
http://archagon.net/blog/2018/03/24/data-laced-with-history/
(I am not affiliated in any way, just enjoyed it very much)
However, I feel that it is worthwhile (necessary?) to completely understand the academic basis for CRDT. A good place to start is Shapiro et al's second paper : https://hal.inria.fr/inria-00555588/document .
In order (sic) to understand the paper you need to have a grasp of Order Theory. This is not terribly hard to get your head around. This is a good place to start: http://jtfmumm.com/blog/2015/11/17/crdt-primer-1-defanging-o... also https://www.wikiwand.com/en/Order_theory and basically stop when you understand this : https://www.wikiwand.com/en/Lattice_(order)
The reason why the formal basis is important is: that's the whole point of CRDT -- previously (been there, got the t-shirt..) folks just made up replication mechanisms they thought would work. Then they build them and embarked on a process of fixing the bugs. Sometimes that took decades. CRDT is nothing new in terms of : software to perform eventually consistent replication. The new thing is that there's a way to formally prove that your bright idea for replication will in fact work (as in : it will converge and it will have the consistency properties you expect). So if you're not seeing that aspect, then you're really not with the program.
btw originally the C stood for Commutative or Convergent, not Conflict-Free. There are plenty of CRDTs that cope with conflicts consistently, rather than being conflict free (e.g. LWW Register).
The core idea of CRDTs are intuitive and easy to understand from an engineering perspective. For me, the academic literature unnecessarily complicates and obscures what's going on, and I would also point newcomers to something like http://archagon.net/blog/2018/03/24/data-laced-with-history/.
It probably has to do with where you are coming from. If you're not a mathematician or theoretical computer scientist, I don't think that reading these documents is going to be a very helpful start.
It made a lot of stuff click for me. HTH someone!
I'm neither Mathematician nor Computer Scientist (I'm an Electrical Engineer), but I have learned not to fear formal notation and advanced abstract concepts. They're really not that hard to understand once the terminology is decoded.
Awhile back I implemented the "become a connection" logic for a project that has purely CRDTs datatypes, and I kind of went back and forth between composing well known CRDTs to model all the possible state, or just implementing the solution as a finite state machine whose CRDT-ability had to be reasoned for this particular purpose. Ending doing the second.
Got the intuition that this is a very nice way to think about distributed software but the right abstractions may not be in place just yet.
Look at _init() here to get a feel of it:
https://github.com/hyperhyperspace/hyperhyperspace-web/blob/...
I think you may have met some of my colleagues working on similar problems at Dweb camp recently.
In the 2012 paper "Logic and Lattices for Distributed Programming" (by Conway, Marczak, Alvaro, Hellerstein, and Maier) they write:
> CvRDTs present two main problems: (a) the programmer bears responsibility for ensuring lattice properties for their methods (commutativity, associativity, idempotence), and (b) CvRDTs only provide guarantees for individual values, not for application logic in general.
They give this example of the second point:
> A replicated, fault-tolerant courseware application assigns students into study teams. It uses two set CvRDTs: one for Students, another for Teams. The application reads a version of Students and inserts the derived element <Alice, Bob> into Teams. Concurrently, Bob is removed from Students by another application replica. The use of CvRDTs ensures that all replicas will eventually agree that Bob is absent from Students, but this is not enough: application-level state is inconsistent unless the derived values in Teams are updated consistently to reflect Bob's removal. This is outside the scope of CvRDT guarantees.
They continue:
> Taken together, the problems with [CvRDTs] present a scope dilemma: a small module (e.g. a set) makes lattice properties easy to inspect and test, but provides only simple semantic guarantees. Large CvRDTs (e.g., an eventually consistent shopping cart) provide higher-level application guarantees but require the programmer to ensure lattice properties hold for a complex module, resulting in software that is difficult to test, maintain, and trust.
This leads to a research project about monotonic logic as a distributed programming paradigm.
One good example is processing items in an SQS queue, where (without enabling FIFO) there is no guarantee of ordering. With a G-Set you can read and merge batches of items (and retry naively) without affecting the outcome.
It does seem like a good way to dodge some of the tough problems that come up in distributed systems.
[0]https://hal.inria.fr/file/index/docid/555588/filename/techre... [1]http://gazagnaire.org/pub/FGM15.pdf
http://archagon.net/blog/2018/03/24/data-laced-with-history/...
I challenge you to do the same!
Something more, some failure stories like [1] would be interesting.