autobee 2.0.0-rc.10 → 2.0.0-rc.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +23 -6
- package/lib/topo.js +25 -2
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -76,8 +76,13 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
76
76
|
this.writers = null
|
|
77
77
|
this.bumping = 0
|
|
78
78
|
|
|
79
|
+
const fastForward = handlers.fastForward || {}
|
|
80
|
+
|
|
79
81
|
// system head to boot from: migrates or fast-forwards depending on its version
|
|
80
|
-
this.bootFrom =
|
|
82
|
+
this.bootFrom = fastForward.boot || null
|
|
83
|
+
|
|
84
|
+
// conservative (default on): only fast-forward onto a head someone can serve whole
|
|
85
|
+
this._conservativeFF = fastForward.conservative !== false
|
|
81
86
|
|
|
82
87
|
this.reboot = null
|
|
83
88
|
this.rebooting = null
|
|
@@ -88,6 +93,7 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
88
93
|
|
|
89
94
|
this._localSystemStart = 0
|
|
90
95
|
this._localSystemLength = 0
|
|
96
|
+
this._localFlushes = 0
|
|
91
97
|
this._localViewStart = 0
|
|
92
98
|
this._localViewLength = 0
|
|
93
99
|
|
|
@@ -163,6 +169,7 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
163
169
|
|
|
164
170
|
this._localSystemStart = this.system.bee.context.local.length
|
|
165
171
|
this._localViewStart = this._workingBee.context.local.length
|
|
172
|
+
this._localFlushes = this.system.flushes
|
|
166
173
|
|
|
167
174
|
this.bumpSoon()
|
|
168
175
|
}
|
|
@@ -603,6 +610,9 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
603
610
|
const target = length >= 0 ? length : core.length
|
|
604
611
|
if (target === 0) return null
|
|
605
612
|
|
|
613
|
+
// conservative: only proceed when a connected peer can serve the head whole
|
|
614
|
+
if (opts && opts.conservative && core.remoteContiguousLength < target) return null
|
|
615
|
+
|
|
606
616
|
const buf = await core.get(target - 1, opts)
|
|
607
617
|
if (buf === null) return null
|
|
608
618
|
|
|
@@ -967,6 +977,7 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
967
977
|
if (local) {
|
|
968
978
|
this._localSystemLength = this.system.bee.context.local.length - this._localSystemStart
|
|
969
979
|
this._localViewLength = this._workingBee.context.local.length - this._localViewStart
|
|
980
|
+
this._localFlushes = this.system.flushes
|
|
970
981
|
}
|
|
971
982
|
|
|
972
983
|
this.writers.attest(witnessed)
|
|
@@ -1081,7 +1092,7 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
1081
1092
|
|
|
1082
1093
|
async _flushLocal() {
|
|
1083
1094
|
await this.writers.flushLocal({
|
|
1084
|
-
flushes: this.
|
|
1095
|
+
flushes: this._localFlushes,
|
|
1085
1096
|
system: {
|
|
1086
1097
|
key: this.system.bee.context.local.key,
|
|
1087
1098
|
start: this._localSystemStart,
|
|
@@ -1096,6 +1107,7 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
1096
1107
|
|
|
1097
1108
|
this._localSystemStart = this.system.bee.context.local.length
|
|
1098
1109
|
this._localSystemLength = 0
|
|
1110
|
+
this._localFlushes = this.system.flushes
|
|
1099
1111
|
this._localViewStart = this._workingBee.context.local.length
|
|
1100
1112
|
this._localViewLength = 0
|
|
1101
1113
|
}
|
|
@@ -1155,7 +1167,9 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
1155
1167
|
}
|
|
1156
1168
|
|
|
1157
1169
|
async _rebootFromHead(head, trusted, { force = false, wait = true } = {}) {
|
|
1158
|
-
const
|
|
1170
|
+
const conservative = !force && this._conservativeFF
|
|
1171
|
+
|
|
1172
|
+
const oplog = await this._getOplog(head.key, head.length, { conservative })
|
|
1159
1173
|
if (!oplog) return null
|
|
1160
1174
|
|
|
1161
1175
|
const verified = trusted ? await this._getOplog(trusted.key, trusted.length) : oplog
|
|
@@ -1168,13 +1182,15 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
1168
1182
|
return null
|
|
1169
1183
|
}
|
|
1170
1184
|
|
|
1171
|
-
const
|
|
1185
|
+
const tip = {
|
|
1172
1186
|
system: batchToHead(oplog.op.views.system),
|
|
1173
1187
|
verified: {
|
|
1174
1188
|
op: trusted || head,
|
|
1175
1189
|
flushes: verified.op.views.flushes
|
|
1176
1190
|
}
|
|
1177
|
-
}
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
const moved = await this._moveTo(batchToHead(verified.op.views.system), tip)
|
|
1178
1194
|
|
|
1179
1195
|
if (moved && wait) return this.reboot.promise
|
|
1180
1196
|
|
|
@@ -1277,7 +1293,8 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
1277
1293
|
const t = await topo.rollback(this, sys, verified)
|
|
1278
1294
|
await sys.close()
|
|
1279
1295
|
|
|
1280
|
-
await this.applyBacklog(t.tip)
|
|
1296
|
+
if (t !== null) await this.applyBacklog(t.tip)
|
|
1297
|
+
|
|
1281
1298
|
return this._update(changes)
|
|
1282
1299
|
}
|
|
1283
1300
|
|
package/lib/topo.js
CHANGED
|
@@ -42,20 +42,35 @@ async function getMostRecentHead(auto, system) {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
async function rollback(auto, system, verified) {
|
|
45
|
+
if (!(await isApplied(system, verified.op))) return null
|
|
46
|
+
|
|
45
47
|
const tip = []
|
|
46
48
|
const ch = system.createChangesStream()
|
|
47
49
|
|
|
50
|
+
let found = false
|
|
51
|
+
|
|
48
52
|
for await (const data of ch) {
|
|
49
53
|
const { ref, info } = getOplog(data)
|
|
54
|
+
|
|
50
55
|
if (sameNode(ref.oplog, verified.op)) {
|
|
51
|
-
|
|
56
|
+
// stale views.flushes - the verified head describes a prefix this system
|
|
57
|
+
// does not share, so nothing above it is ours to reapply
|
|
58
|
+
if (info.flushes === verified.flushes) found = true
|
|
59
|
+
break
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// walking back, a writer's lengths only decrease - once this writer is
|
|
63
|
+
// behind the verified head the marker cannot be further down
|
|
64
|
+
if (b4a.equals(ref.oplog.key, verified.op.key) && ref.oplog.length < verified.op.length) {
|
|
52
65
|
break
|
|
53
66
|
}
|
|
54
67
|
|
|
55
68
|
tip.push(ref)
|
|
56
69
|
}
|
|
57
70
|
|
|
58
|
-
|
|
71
|
+
if (!found) return null
|
|
72
|
+
|
|
73
|
+
const inflated = await inflate(auto, tip.reverse())
|
|
59
74
|
|
|
60
75
|
// @todo: verify sort
|
|
61
76
|
|
|
@@ -86,6 +101,14 @@ async function replay(auto) {
|
|
|
86
101
|
return inflated.flatMap((b) => (b === null ? [null] : b.batch))
|
|
87
102
|
}
|
|
88
103
|
|
|
104
|
+
async function isApplied(system, node) {
|
|
105
|
+
const entry = await system.get(encoding.encodeSystemWriterKey(node.key))
|
|
106
|
+
if (entry === null) return false
|
|
107
|
+
|
|
108
|
+
const info = encoding.decodeSystemWriter(entry.key, entry.value)
|
|
109
|
+
return info.length >= node.length
|
|
110
|
+
}
|
|
111
|
+
|
|
89
112
|
// tolerates legacy nodes instead of asserting
|
|
90
113
|
async function* oplogIterator(bee) {
|
|
91
114
|
try {
|