gun - 如何使用 Gun 实现无损 CRDT?
问题描述
如何使用 Gun 创建 CRDT?
例如,如果我想实现一个只增长的数组,其中每个元素都指向下一个元素,我该如何解决冲突?
为简化起见,让我们创建一个 Alice 和 Bob 合作的场景。
该数组包含 3 个元素,[a, b, d]
.
这个数组的内部表示将是一个像这样的链表:
a => b => c
(当然,内部表示形式类似于{value: 'a', next: { value: 'b' next: { value: 'c' }}})
,但我认为您使用更简洁的表示法理解了我的观点。
Alice 现在想在和c
之间插入元素。b
d
同时,Bob 想要在和C
之间插入元素。b
d
同时,它们具有数组的这种内部表示:
爱丽丝:a => b => c => d
鲍勃:a => b => C => d
当他们加入 CRDT 时,他们将收敛到以下值之一:
a => b => c => C => d
或者
a => b => C => c => d
无论如何,a)它们都将收敛于相同的值,并且 b)它们不会丢失彼此的数据。
我们可以使用 Gun 来实现这一点吗?
解决方案
是的。
这是几年前的代码演示:
您可以在 GUN 的基础 CRDT 之上创建任何其他 CRDT 作为数据结构。
我们甚至对这类东西的通用算法做了一个完整的卡通解释:
https://gun.eco/explainers/school/class.html
(或者从https://youtu.be/yCcWpzY8dIA?t=29m36s开始,由精彩的 Martin Kleppmann 查看针对特定案例实施的更详细说明)
我还没有看到任何人专门在 GUN 之上实现 RGA,但考虑到您发送的代码有多短,它应该很容易。(虽然“删除”需要是一个空墓碑,但这很好)
从查看计数器 CRDT 开始可能是最简单的,“如何开始使用自定义扩展将数据保存到 GUN”,这是一个仅包含 12 行代码的增长型 CRDT:
您注意到它非常基本,RGA 会很相似,您可能会有一些 GUN 扩展(只是一个 JS 方法/函数,这使得开发人员更容易使用),比如
Gun.chain.rga = function(
...
然后在内部,就像使用计数器一样,您可以调用gun.put(
orgun.set(
或任何其他命令将数据保存到图中(put 和 set 本身只是 RGA 之类的扩展,这里没什么特别的),您将在其中构建/构造图/树/table,或者你可能很懒,只是做一些类似的事情:
// fictional code
var myData = {
rgaTree: {left: {}, right: {}}
}
myData.rgaTree.left.next = myData.rgaTree.right;
myData.rgaTree.right.prev = myData.rgaTree.left;
// yes! circular references are supported!
gun.put(myData);
显然,您可能希望更详细并使用 cuid 和其他东西来控制 UUID,但您明白了。
没有理由直接直接替换 HAM CRDT 或“注入”一个 CRDT,只是 @pgte 会在 GUN 上对 CRDT 的数据结构进行建模(可能通过 GUN 扩展使用一个很好的简单 API),然后你也会有该扩展支持回调,如果将其传递给您gun.get(
...通过 RGA 图/树并运行各种 RGA 逻辑,然后将结果吐回给开发人员。这棵树可以在 GUN 内部由许多对等方同时动态变异,比如 Alice 和 Bob!
然后,GUN 将通过(许多)存储引擎之一(例如 IPFS!)将动态更改和更新的数据保存到磁盘,因此 IPFS 可以随着时间的推移托管数据的持久性,并且 GUN 可以管理 O(1) 树查找是可变/变化/动态树/图/索引结构。
推荐阅读
- regex - 提取两个标记之间的文本并替换一个字符
- python - 提交并仍然停留在相同的 url
- visual-studio - Windows 上的 Visual Studio iOS 项目 > iOS 捆绑签名 > Xamarin 自动预配获取“自动签名失败”
- android - android如何检测Edittext中的多个字符串值
- bash - 使用通配符将多个文件从一个子目录复制到另一个
- python - 在弹性 beantalk 上配置 django admin
- database - 在显示对象列表时,我应该检索完整对象列表还是仅检索对象的必要部分
- python - 从 Dataframe 中删除行会导致在 Python 中分发数据框
- javascript - 无法读取 null 的属性“textContent”
- php - 是否可以调试此 PHP