autobee 2.0.0-rc.12 → 2.0.0-rc.14
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 +8 -0
- package/lib/topo.js +49 -44
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -57,6 +57,7 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
57
57
|
this.id = null
|
|
58
58
|
this.bootstrap = null
|
|
59
59
|
this.handlers = handlers
|
|
60
|
+
this.stats = { undos: 0, fastForwards: 0, drains: 0, applies: 0, appends: 0 }
|
|
60
61
|
|
|
61
62
|
this.system = new System(this.store.namespace('system'), this.name, {
|
|
62
63
|
getEncryptionProvider: this.getSystemEncryption,
|
|
@@ -498,6 +499,8 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
498
499
|
async _drain() {
|
|
499
500
|
if (this._updating) await this._updating
|
|
500
501
|
|
|
502
|
+
this.stats.drains++
|
|
503
|
+
|
|
501
504
|
if (this.bootFrom) {
|
|
502
505
|
await this._initFromHead(this.bootFrom)
|
|
503
506
|
this.bootFrom = null
|
|
@@ -919,6 +922,7 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
919
922
|
const t = await topo.sort(this, batch)
|
|
920
923
|
|
|
921
924
|
if (t.undo) {
|
|
925
|
+
this.stats.undos++
|
|
922
926
|
t.view = await this.system.undo(t.undo)
|
|
923
927
|
}
|
|
924
928
|
|
|
@@ -967,6 +971,7 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
967
971
|
}
|
|
968
972
|
|
|
969
973
|
if (this._hasApply && (await this.system.canApply(batch[0].key, optimistic))) {
|
|
974
|
+
this.stats.applies++
|
|
970
975
|
this._host.applying = batch
|
|
971
976
|
await this._handlers.apply(userBatch, this._workingView, this._host)
|
|
972
977
|
this._host.applying = null
|
|
@@ -1035,6 +1040,8 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
1035
1040
|
async append(values, { optimistic = false } = {}) {
|
|
1036
1041
|
if (this.closing) throw new Error('Autobee closed')
|
|
1037
1042
|
|
|
1043
|
+
this.stats.appends++
|
|
1044
|
+
|
|
1038
1045
|
if (!Array.isArray(values)) values = [values]
|
|
1039
1046
|
|
|
1040
1047
|
if (!this.opened) await this.ready()
|
|
@@ -1272,6 +1279,7 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
1272
1279
|
|
|
1273
1280
|
await this._update(changes)
|
|
1274
1281
|
|
|
1282
|
+
this.stats.fastForwards++
|
|
1275
1283
|
this.emit('move-to', to, from)
|
|
1276
1284
|
this.reboot.resolve({ to, from })
|
|
1277
1285
|
|
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
|