autobee 2.0.0-rc.11 → 2.0.0-rc.13
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 +12 -2
- package/lib/topo.js +49 -44
- 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
|
|
@@ -605,6 +610,9 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
605
610
|
const target = length >= 0 ? length : core.length
|
|
606
611
|
if (target === 0) return null
|
|
607
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
|
+
|
|
608
616
|
const buf = await core.get(target - 1, opts)
|
|
609
617
|
if (buf === null) return null
|
|
610
618
|
|
|
@@ -1159,7 +1167,9 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
1159
1167
|
}
|
|
1160
1168
|
|
|
1161
1169
|
async _rebootFromHead(head, trusted, { force = false, wait = true } = {}) {
|
|
1162
|
-
const
|
|
1170
|
+
const conservative = !force && this._conservativeFF
|
|
1171
|
+
|
|
1172
|
+
const oplog = await this._getOplog(head.key, head.length, { conservative })
|
|
1163
1173
|
if (!oplog) return null
|
|
1164
1174
|
|
|
1165
1175
|
const verified = trusted ? await this._getOplog(trusted.key, trusted.length) : oplog
|
package/lib/topo.js
CHANGED
|
@@ -36,9 +36,14 @@ class Clock {
|
|
|
36
36
|
async function getMostRecentHead(auto, system) {
|
|
37
37
|
const ch = system.createChangesStream()
|
|
38
38
|
for await (const data of ch) {
|
|
39
|
-
const
|
|
40
|
-
|
|
39
|
+
const refs = getOplogCompat(data)
|
|
40
|
+
if (!refs.length) continue
|
|
41
|
+
|
|
42
|
+
const { oplog } = refs[0]
|
|
43
|
+
return { key: oplog.key, length: oplog.length }
|
|
41
44
|
}
|
|
45
|
+
|
|
46
|
+
return null
|
|
42
47
|
}
|
|
43
48
|
|
|
44
49
|
async function rollback(auto, system, verified) {
|
|
@@ -109,48 +114,6 @@ async function isApplied(system, node) {
|
|
|
109
114
|
return info.length >= node.length
|
|
110
115
|
}
|
|
111
116
|
|
|
112
|
-
// tolerates legacy nodes instead of asserting
|
|
113
|
-
async function* oplogIterator(bee) {
|
|
114
|
-
try {
|
|
115
|
-
for await (const node of bee.createChangesStream({ wait: false })) {
|
|
116
|
-
const legacy = isLegacyNode(node)
|
|
117
|
-
const refs = getOplogs(node)
|
|
118
|
-
if (refs.length) yield { node, refs, legacy }
|
|
119
|
-
}
|
|
120
|
-
} catch {
|
|
121
|
-
yield null // signal data not available
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// legacy nodes carry no isOplog flag so we cannot tell which writer update is
|
|
126
|
-
// the oplog to fetch - yield every candidate until we have a better signal
|
|
127
|
-
function getOplogs(data) {
|
|
128
|
-
const undo = data.tail || EMPTY_HEAD
|
|
129
|
-
const oplogs = []
|
|
130
|
-
const candidates = []
|
|
131
|
-
|
|
132
|
-
for (const { keys } of data.batch) {
|
|
133
|
-
for (const k of keys) {
|
|
134
|
-
if (k.key[0] !== 1) continue
|
|
135
|
-
|
|
136
|
-
let value = null
|
|
137
|
-
try {
|
|
138
|
-
value = encoding.decodeSystemWriter(k.key, k.value)
|
|
139
|
-
} catch {
|
|
140
|
-
continue
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// writer was just added, nothing to fetch
|
|
144
|
-
if (!value.length) continue
|
|
145
|
-
|
|
146
|
-
if (value.isOplog) oplogs.push({ undo, oplog: value })
|
|
147
|
-
else candidates.push({ undo, oplog: value })
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
return oplogs.length ? oplogs : candidates
|
|
152
|
-
}
|
|
153
|
-
|
|
154
117
|
async function sort(auto, batch) {
|
|
155
118
|
const node = batch[0]
|
|
156
119
|
const ch = auto.system.bee.createChangesStream()
|
|
@@ -366,6 +329,19 @@ function getLocalBatch(undo, writer, length, weight, index) {
|
|
|
366
329
|
return getOplogBatch(undo, writer.core, length, weight, index)
|
|
367
330
|
}
|
|
368
331
|
|
|
332
|
+
// tolerates legacy nodes instead of asserting
|
|
333
|
+
async function* oplogIterator(bee) {
|
|
334
|
+
try {
|
|
335
|
+
for await (const node of bee.createChangesStream({ wait: false })) {
|
|
336
|
+
const legacy = isLegacyNode(node)
|
|
337
|
+
const refs = getOplogCompat(node)
|
|
338
|
+
if (refs.length) yield { node, refs, legacy }
|
|
339
|
+
}
|
|
340
|
+
} catch {
|
|
341
|
+
yield null // signal data not available
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
369
345
|
function getOplog(data) {
|
|
370
346
|
const result = { ref: null, info: null }
|
|
371
347
|
for (const { keys } of data.batch) {
|
|
@@ -391,6 +367,35 @@ function getOplog(data) {
|
|
|
391
367
|
asserts.bail('Bad system node')
|
|
392
368
|
}
|
|
393
369
|
|
|
370
|
+
// legacy nodes carry no isOplog flag so we cannot tell which writer update is
|
|
371
|
+
// the oplog to fetch - yield every candidate until we have a better signal
|
|
372
|
+
function getOplogCompat(data) {
|
|
373
|
+
const undo = data.tail || EMPTY_HEAD
|
|
374
|
+
const oplogs = []
|
|
375
|
+
const candidates = []
|
|
376
|
+
|
|
377
|
+
for (const { keys } of data.batch) {
|
|
378
|
+
for (const k of keys) {
|
|
379
|
+
if (k.key[0] !== 1) continue
|
|
380
|
+
|
|
381
|
+
let value = null
|
|
382
|
+
try {
|
|
383
|
+
value = encoding.decodeSystemWriter(k.key, k.value)
|
|
384
|
+
} catch {
|
|
385
|
+
continue
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// writer was just added, nothing to fetch
|
|
389
|
+
if (!value.length) continue
|
|
390
|
+
|
|
391
|
+
if (value.isOplog) oplogs.push({ undo, oplog: value })
|
|
392
|
+
else candidates.push({ undo, oplog: value })
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
return oplogs.length ? oplogs : candidates
|
|
397
|
+
}
|
|
398
|
+
|
|
394
399
|
function isLinking(node, link) {
|
|
395
400
|
if (node.length >= link.length && b4a.equals(node.key, link.key)) {
|
|
396
401
|
return true
|