autobee 2.5.1 → 2.5.3

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/README.md CHANGED
@@ -133,6 +133,12 @@ Optionally pass `{ optimistic: true }` to write without waiting to be a confirme
133
133
  await db.append(buf, { optimistic: true })
134
134
  ```
135
135
 
136
+ An optimistic node always reaches `apply`, whoever wrote it, and is always
137
+ recorded afterwards. `apply` decides what it does: call `host.addWriter` to
138
+ grant the writer, or do nothing to leave it unwritable. An op `apply` does not
139
+ accept must be handled in `apply` (ie. ignored) - throwing is a bug, as for any
140
+ other node, and closes the db.
141
+
136
142
  #### `await db.update()`
137
143
 
138
144
  Trigger a new apply cycle. Useful after replication to process new data.
@@ -216,7 +222,8 @@ Remove a writer by public key (Buffer or hex string).
216
222
 
217
223
  #### `host.ackWriter(key)`
218
224
 
219
- Acknowledge a writer without changing their permissions.
225
+ Deprecated, a no-op. Optimistic nodes are always recorded once applied, whether
226
+ or not apply acks the writer. Kept so existing apply functions keep working.
220
227
 
221
228
  #### `host.interrupt(reason)`
222
229
 
package/index.js CHANGED
@@ -690,10 +690,7 @@ module.exports = class Autobee extends ReadyResource {
690
690
  break // revaluate conditions...
691
691
  }
692
692
 
693
- if (await this._bumpPendingWriters()) {
694
- this._needsUpdate = true
695
- continue
696
- }
693
+ if (await this._bumpPendingWriters()) continue
697
694
 
698
695
  if (!(await this._appendAck())) break
699
696
  this._needsUpdate = true
@@ -1156,7 +1153,10 @@ module.exports = class Autobee extends ReadyResource {
1156
1153
  if (!local && this._catchupMigratedNodes !== null) {
1157
1154
  const updated = await this._bumpMigratedWriters()
1158
1155
  this._catchupMigratedNodes = null
1159
- if (updated) return true
1156
+ if (updated) {
1157
+ this._needsUpdate = true
1158
+ return true
1159
+ }
1160
1160
  }
1161
1161
 
1162
1162
  // apply the best next node to keep the prefix stable
@@ -1165,56 +1165,17 @@ module.exports = class Autobee extends ReadyResource {
1165
1165
 
1166
1166
  const { writer: w, batch } = next
1167
1167
 
1168
- if (w.isAdded || (w.isRemoved && w.hasReferrals())) {
1169
- await this._processBatch(batch)
1170
- w.notify(batch)
1171
- return true
1172
- }
1168
+ const optimistic = this.optimistic && batch[0].optimistic
1173
1169
 
1174
- if (this.optimistic && !w.isRemoved && batch[0].optimistic) {
1175
- if (!(await this._optimisticBatch(batch))) {
1176
- w.removePending()
1177
- return true
1178
- }
1179
- w.notify(batch)
1170
+ if (optimistic || w.isAdded || (w.isRemoved && w.hasReferrals())) {
1171
+ await this._processBatch(batch)
1172
+ } else {
1173
+ w.removePending()
1180
1174
  return true
1181
1175
  }
1182
1176
 
1183
- // not added and not applicable optimistically: nothing can apply this
1184
- // batch now, so drop the writer for this drain instead of reselecting it
1185
- // (a refresh re-adds it once it has been added or has new blocks)
1186
- w.removePending()
1187
- return true
1188
- }
1189
-
1190
- async _optimisticBatch(batch) {
1191
- const rollbackSystem = this.system.bee.head()
1192
- const rollbackView = this._workingBee.head()
1193
-
1194
- const t = await this.prepareBatch(batch)
1195
- if (t.view) this._workingBee.move(t.view)
1196
-
1197
- for (const b of t.tip) {
1198
- const optimistic = b[0].optimistic
1199
- let accepted = false
1200
- try {
1201
- accepted = await this._applyBatch(b, optimistic)
1202
- } catch (err) {
1203
- if (!optimistic) throw err
1204
- }
1205
-
1206
- // only check if batch was successful
1207
- if (b !== batch) continue
1208
-
1209
- // declined: apply threw, or never called addWriter/ackWriter for this writer
1210
- if (!accepted) {
1211
- this._workingBee.move(rollbackView)
1212
- this.system.bee.move(rollbackSystem)
1213
- await this.system.reset()
1214
- return false
1215
- }
1216
- }
1217
-
1177
+ w.notify(batch)
1178
+ this._needsUpdate = true
1218
1179
  return true
1219
1180
  }
1220
1181
 
@@ -1301,8 +1262,10 @@ module.exports = class Autobee extends ReadyResource {
1301
1262
  }
1302
1263
  }
1303
1264
 
1304
- // read before flush clears it
1305
- const accepted = this.system.touched(batch[0].key)
1265
+ // an optimistic node is always consumed: record its length and, unless apply
1266
+ // granted the writer, record the writer as removed so that only its
1267
+ // optimistic nodes reach apply
1268
+ if (optimistic) await this.system.ackWriter(batch[0].key)
1306
1269
 
1307
1270
  const changed = await this.system.flush(batch, this._workingBee)
1308
1271
 
@@ -1318,8 +1281,6 @@ module.exports = class Autobee extends ReadyResource {
1318
1281
  if (added) await this.writers.add(key)
1319
1282
  else await this.writers.remove(key)
1320
1283
  }
1321
-
1322
- return accepted
1323
1284
  }
1324
1285
 
1325
1286
  async _storeBoot() {
@@ -1418,7 +1379,7 @@ module.exports = class Autobee extends ReadyResource {
1418
1379
  async _flushLocal() {
1419
1380
  // pull any available local nodes in before flushing
1420
1381
  while (!this._interrupting && (await this._bumpPendingWriters({ local: true }))) {
1421
- this._needsUpdate = true
1382
+ // a bump that applied a batch flags the update itself
1422
1383
  }
1423
1384
 
1424
1385
  const flushed = await this.writers.flushLocal({
@@ -41,10 +41,10 @@ class ApplyCalls {
41
41
  return this.auto.system.addWriter(key, { weight, isGenesis, coord, carrier })
42
42
  }
43
43
 
44
- ackWriter(key) {
45
- if (typeof key === 'string') key = ID.decode(key)
46
- return this.auto.system.ackWriter(key)
47
- }
44
+ // deprecated: every optimistic node is recorded once applied, whether or not
45
+ // apply acks its writer, so this has nothing left to do. kept so contracts
46
+ // written against older versions keep applying
47
+ ackWriter() {}
48
48
 
49
49
  removeWriter(key) {
50
50
  if (typeof key === 'string') key = ID.decode(key)
package/lib/system.js CHANGED
@@ -90,10 +90,12 @@ module.exports = class Systembee {
90
90
  if (length === 0) {
91
91
  length = info ? info.length : 0
92
92
  }
93
- // acked but never granted: keep the op (record its length) but record the
94
- // writer as removed so nothing else from it is applied
95
- const isRemoved = !info || info.isAdded === false
96
- this.update(key, length, -1, -1, false, false, isRemoved, -1, null)
93
+ // called for every optimistic node once applied. not granted (unknown,
94
+ // ack-only or removed): keep the op (record its length) but record the
95
+ // writer as removed - it is not writable and only its optimistic ops reach apply
96
+ const w = this.writers.get(b4a.toString(key, 'hex'))
97
+ const granted = w ? w.added : info !== null && info.isAdded !== false && !info.isRemoved
98
+ this.update(key, length, -1, -1, false, false, !granted, -1, null)
97
99
  }
98
100
 
99
101
  async removeWriter(key, { length = 0 } = {}) {
@@ -227,17 +229,15 @@ module.exports = class Systembee {
227
229
  this.update(node.key, node.length, node.weight, -1, false, false, false, node.timestamp, null)
228
230
  }
229
231
 
230
- // did this apply add or remove (ack) the writer
231
- touched(key) {
232
- return this.writers.has(b4a.toString(key, 'hex'))
233
- }
234
-
235
232
  async canApply(key, optimistic) {
233
+ // an optimistic node always reaches apply, whether its writer is unknown,
234
+ // acked or removed - it is self-verifying, apply decides what it does
235
+ if (optimistic) return true
236
236
  const id = b4a.toString(key, 'hex')
237
237
  const w = this.writers.get(id)
238
238
  if (w) return w.added
239
239
  const info = await this.get(key)
240
- return info ? !info.isRemoved : !!optimistic
240
+ return info ? !info.isRemoved : false
241
241
  }
242
242
 
243
243
  snapshot(head = null) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "autobee",
3
- "version": "2.5.1",
3
+ "version": "2.5.3",
4
4
  "description": "Bee based autobase",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Holepunch Inc.",