autobee 2.0.0-rc.18 → 2.0.0-rc.19

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.
Files changed (3) hide show
  1. package/index.js +16 -23
  2. package/lib/writers.js +46 -1
  3. package/package.json +1 -1
package/index.js CHANGED
@@ -909,35 +909,28 @@ module.exports = class Autobee extends ReadyResource {
909
909
  this._catchupMigratedNodes = null
910
910
  }
911
911
 
912
- let updated = false
912
+ // apply the best next node to keep the prefix stable
913
+ const next = await this.writers.nextPendingNode()
914
+ if (next === null) return false
913
915
 
914
- const pending = this.writers.pending.slice()
916
+ const { writer: w, batch } = next
915
917
 
916
- for (let i = pending.length - 1; i >= 0; i--) {
917
- const w = pending[i]
918
-
919
- const batch = await w.next()
920
- if (batch === null) continue
921
-
922
- if (w.isAdded || (w.isRemoved && w.hasReferrals())) {
923
- await this._processBatch(batch)
924
- w.notify(batch)
925
- updated = true
926
- continue
927
- }
918
+ if (w.isAdded || (w.isRemoved && w.hasReferrals())) {
919
+ await this._processBatch(batch)
920
+ w.notify(batch)
921
+ return true
922
+ }
928
923
 
929
- if (this.optimistic && !w.isRemoved && batch[0].optimistic) {
930
- if (!(await this._optimisticBatch(batch))) {
931
- w.removePending()
932
- continue
933
- }
934
- w.notify(batch)
935
- updated = true
936
- continue
924
+ if (this.optimistic && !w.isRemoved && batch[0].optimistic) {
925
+ if (!(await this._optimisticBatch(batch))) {
926
+ w.removePending()
927
+ return true
937
928
  }
929
+ w.notify(batch)
930
+ return true
938
931
  }
939
932
 
940
- return updated
933
+ return true
941
934
  }
942
935
 
943
936
  async _optimisticBatch(batch) {
package/lib/writers.js CHANGED
@@ -1,7 +1,7 @@
1
1
  const b4a = require('b4a')
2
2
  const encoding = require('./encoding.js')
3
3
  const Triggers = require('./triggers.js')
4
- const { signAttestation } = require('./witness.js')
4
+ const { signAttestation, resolveWeight } = require('./witness.js')
5
5
  const { WriterEncryption } = require('autobee-encryption')
6
6
 
7
7
  const WRITER_PREFETCH = 10
@@ -25,6 +25,8 @@ class ActiveWriters {
25
25
  this.witnesses = []
26
26
  this.attestations = []
27
27
 
28
+ this._pendingBuffer = new Map()
29
+
28
30
  this.localWriter.attach()
29
31
 
30
32
  this._bootstrap()
@@ -115,6 +117,9 @@ class ActiveWriters {
115
117
  }
116
118
 
117
119
  async refresh() {
120
+ // peeked batches were read against the pre-reboot system, drop them
121
+ this._pendingBuffer.clear()
122
+
118
123
  if (this.localWriter && !this.localWriter.isClosed) {
119
124
  await this.updateLocalState()
120
125
  }
@@ -129,6 +134,33 @@ class ActiveWriters {
129
134
  await this.localWriter.update()
130
135
  }
131
136
 
137
+ async nextPendingNode() {
138
+ for (const w of this.pending.slice()) {
139
+ if (this._pendingBuffer.has(w) || w.isFrozen) continue
140
+
141
+ const batch = await w.next()
142
+ if (batch !== null) this._pendingBuffer.set(w, batch)
143
+ }
144
+
145
+ if (this._pendingBuffer.size === 0) return null
146
+
147
+ let writer = null
148
+ let best = null
149
+
150
+ for (const [w, batch] of this._pendingBuffer) {
151
+ const head = batch[0]
152
+ // -1 marks a node next() has not resolved a sort weight for yet
153
+ if (head.weight < 0) head.weight = await resolveWeight(this.auto, head)
154
+ if (best === null || sortsBefore(head, best[0])) {
155
+ writer = w
156
+ best = batch
157
+ }
158
+ }
159
+
160
+ this._pendingBuffer.delete(writer)
161
+ return { writer, batch: best }
162
+ }
163
+
132
164
  _updateLocalState() {
133
165
  const w = this.localWriter
134
166
 
@@ -314,6 +346,8 @@ class Writer {
314
346
  if (!this.isPending) return
315
347
  this.isPending = false
316
348
 
349
+ this.writers._pendingBuffer.delete(this)
350
+
317
351
  const head = this.writers.pending.pop()
318
352
  if (head !== this) {
319
353
  this.writers.pending[this.index] = head
@@ -702,6 +736,17 @@ class Writer {
702
736
  }
703
737
  }
704
738
 
739
+ // mirrors topo.cmp - kept local because topo.js requires this module
740
+ function sortsBefore(a, b) {
741
+ if (a.weight !== b.weight) return a.weight > b.weight
742
+ if (a.timestamp !== b.timestamp) return a.timestamp < b.timestamp
743
+
744
+ const c = b4a.compare(a.key, b.key)
745
+ if (c !== 0) return c < 0
746
+
747
+ return a.length < b.length
748
+ }
749
+
705
750
  exports.ActiveWriters = ActiveWriters
706
751
  exports.Writer = Writer
707
752
  exports.createNode = createNode
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "autobee",
3
- "version": "2.0.0-rc.18",
3
+ "version": "2.0.0-rc.19",
4
4
  "description": "Bee based autobase",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Holepunch Inc.",