hypercore 11.33.1 → 11.33.2

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
@@ -522,6 +522,15 @@ Info {
522
522
  }
523
523
  ```
524
524
 
525
+ #### `await core.setGroup(topic)`
526
+
527
+ > [!IMPORTANT]
528
+ > This feature is _experimental_. The API is subject to change, and everything may break.
529
+
530
+ Set the group `topic` that the hypercore belongs to. Useful for grouping hypercores together that need to update a larger data structure (eg. `autobee`) that is comprised of them. See `corestore`'s `store.notifyGroup(topic)` for more details.
531
+
532
+ `topic` is a 32 byte buffer. A hypercore can only have one `topic`.
533
+
525
534
  #### `await core.startMarking()`
526
535
 
527
536
  This enables marking mode for the "mark & sweep" approach to clear hypercore storage. When called the current markings are cleared.
package/index.js CHANGED
@@ -719,7 +719,7 @@ class Hypercore extends EventEmitter {
719
719
  once = false
720
720
  this._findingPeers--
721
721
  if (this.core !== null && --this.core.replicator.findingPeers === 0) {
722
- this.core.replicator.updateAll()
722
+ this.core.replicator.queueUpdateAll()
723
723
  }
724
724
  }
725
725
  }
package/lib/replicator.js CHANGED
@@ -48,8 +48,8 @@ const SCALE_LATENCY = 50
48
48
  const NOT_DOWNLOADING_SLACK = (20000 + Math.random() * 20000) | 0
49
49
  const MAX_PEERS_UPGRADE = 3
50
50
  const LAST_BLOCKS = 256
51
-
52
51
  const MAX_RANGES = 64
52
+ const MIN_PEER_UPDATE_ALL = 40
53
53
 
54
54
  const NOT_AVAILABLE = 1
55
55
  const INVALID_REQUEST = 2
@@ -753,7 +753,7 @@ class Peer {
753
753
 
754
754
  if (this.remoteOpened === false) {
755
755
  this.replicator._ifAvailable--
756
- this.replicator.updateAll()
756
+ this.replicator.queueUpdateAll()
757
757
  return
758
758
  }
759
759
 
@@ -1297,7 +1297,7 @@ class Peer {
1297
1297
  const req = request > 0 ? this.replicator._inflight.get(request) : null
1298
1298
 
1299
1299
  if (req === null || req.peer !== this) {
1300
- this.replicator.updateAll()
1300
+ this.replicator.queueUpdateAll()
1301
1301
  return
1302
1302
  }
1303
1303
 
@@ -2020,6 +2020,9 @@ module.exports = class Replicator {
2020
2020
  this._notDownloadingLinger = notDownloadingLinger
2021
2021
  this._notDownloadingTimer = null
2022
2022
 
2023
+ this._updateAllBump = null
2024
+ this._updateAllBound = this.updateAll.bind(this)
2025
+
2023
2026
  const self = this
2024
2027
  this._onstreamclose = onstreamclose
2025
2028
 
@@ -2202,7 +2205,7 @@ module.exports = class Replicator {
2202
2205
 
2203
2206
  const ref = this._addUpgrade().attach(session)
2204
2207
 
2205
- this.updateAll()
2208
+ this.queueUpdateAll()
2206
2209
 
2207
2210
  return ref
2208
2211
  }
@@ -2212,7 +2215,7 @@ module.exports = class Replicator {
2212
2215
  const ref = b.attach(session)
2213
2216
 
2214
2217
  this._queueBlock(b)
2215
- this.updateAll()
2218
+ this.queueUpdateAll()
2216
2219
 
2217
2220
  return ref
2218
2221
  }
@@ -2222,7 +2225,7 @@ module.exports = class Replicator {
2222
2225
  const ref = s.attach(session)
2223
2226
 
2224
2227
  this._seeks.push(s)
2225
- this.updateAll()
2228
+ this.queueUpdateAll()
2226
2229
 
2227
2230
  return ref
2228
2231
  }
@@ -2257,7 +2260,7 @@ module.exports = class Replicator {
2257
2260
  return ref
2258
2261
  }
2259
2262
 
2260
- this.updateAll()
2263
+ this.queueUpdateAll()
2261
2264
 
2262
2265
  return ref
2263
2266
  }
@@ -2279,7 +2282,7 @@ module.exports = class Replicator {
2279
2282
  }
2280
2283
 
2281
2284
  for (const replicator of updated) {
2282
- replicator.updateAll()
2285
+ replicator.queueUpdateAll()
2283
2286
  }
2284
2287
  }
2285
2288
 
@@ -2291,7 +2294,7 @@ module.exports = class Replicator {
2291
2294
  cleared = true
2292
2295
  }
2293
2296
 
2294
- if (cleared) this.updateAll()
2297
+ if (cleared) this.queueUpdateAll()
2295
2298
  }
2296
2299
 
2297
2300
  _matchingRequest(req, data) {
@@ -2452,7 +2455,7 @@ module.exports = class Replicator {
2452
2455
 
2453
2456
  this._onpeerupdate(false, peer)
2454
2457
  if (inflight) {
2455
- this.updateAll()
2458
+ this.queueUpdateAll()
2456
2459
  } else {
2457
2460
  this._checkUpgradeIfAvailable()
2458
2461
  }
@@ -2645,7 +2648,7 @@ module.exports = class Replicator {
2645
2648
  this._updatesPending = 0
2646
2649
  }
2647
2650
 
2648
- if (this._inflight.idle || updateAll) this.updateAll()
2651
+ if (this._inflight.idle || updateAll) this.queueUpdateAll()
2649
2652
  }
2650
2653
 
2651
2654
  _clearRequest(peer, req) {
@@ -2694,7 +2697,7 @@ module.exports = class Replicator {
2694
2697
  this._clearRequest(peer, req)
2695
2698
  }
2696
2699
 
2697
- this.updateAll()
2700
+ this.queueUpdateAll()
2698
2701
  }
2699
2702
 
2700
2703
  _openSkipBitfield() {
@@ -2817,7 +2820,7 @@ module.exports = class Replicator {
2817
2820
  const f = this._addReorg(data.fork, peer)
2818
2821
 
2819
2822
  if (f === null) {
2820
- this.updateAll()
2823
+ this.queueUpdateAll()
2821
2824
  return
2822
2825
  }
2823
2826
 
@@ -2838,7 +2841,7 @@ module.exports = class Replicator {
2838
2841
  }
2839
2842
  }
2840
2843
 
2841
- this.updateAll()
2844
+ this.queueUpdateAll()
2842
2845
  }
2843
2846
 
2844
2847
  // Never throws, allowed to run in the background
@@ -2878,7 +2881,7 @@ module.exports = class Replicator {
2878
2881
  for (const f of old) f.resolve()
2879
2882
  f.resolve()
2880
2883
 
2881
- this.updateAll()
2884
+ this.queueUpdateAll()
2882
2885
  }
2883
2886
 
2884
2887
  _maybeUpdate() {
@@ -3000,16 +3003,30 @@ module.exports = class Replicator {
3000
3003
  this._checkUpgradeIfAvailable()
3001
3004
  }
3002
3005
 
3003
- updateAll() {
3006
+ updateSubset() {
3007
+ return this.updateAll(false)
3008
+ }
3009
+
3010
+ updateAll(all = true) {
3011
+ // Clear queued scan if a full scan
3012
+ if (this._updateAllBump !== null && all) {
3013
+ clearTimeout(this._updateAllBump)
3014
+ this._updateAllBump = null
3015
+ }
3016
+
3004
3017
  // Quick shortcut to wait for flushing reorgs - not needed but less waisted requests
3005
3018
  if (this._applyingReorg !== null) return
3006
3019
 
3007
3020
  const peers = new RandomIterator(this.peers)
3008
3021
 
3022
+ const limit = all ? peers.length : MIN_PEER_UPDATE_ALL
3023
+ let tried = 0
3009
3024
  for (const peer of peers) {
3025
+ tried++
3010
3026
  if (this._updatePeer(peer) === true) {
3011
3027
  peers.requeue()
3012
3028
  }
3029
+ if (tried >= limit) break
3013
3030
  }
3014
3031
 
3015
3032
  // Check if we can skip the non primary check fully
@@ -3018,15 +3035,33 @@ module.exports = class Replicator {
3018
3035
  return
3019
3036
  }
3020
3037
 
3038
+ tried = 0
3021
3039
  for (const peer of peers.restart()) {
3040
+ tried++
3022
3041
  if (this._updatePeerNonPrimary(peer) === true) {
3023
3042
  peers.requeue()
3024
3043
  }
3044
+ if (tried >= limit) break
3025
3045
  }
3026
3046
 
3027
3047
  this._checkUpgradeIfAvailable()
3028
3048
  }
3029
3049
 
3050
+ getUpdateAllDelay(peers) {
3051
+ return Math.min(3000, Math.max(100, (peers.length - MIN_PEER_UPDATE_ALL) * 5))
3052
+ }
3053
+
3054
+ queueUpdateAll() {
3055
+ if (this.peers.length < MIN_PEER_UPDATE_ALL) return this.updateAll()
3056
+
3057
+ // Immediately scan subset
3058
+ this.updateSubset()
3059
+
3060
+ // Schedule full scan
3061
+ if (this._updateAllBump !== null) return //skip if already scheduled
3062
+ this._updateAllBump = setTimeout(this._updateAllBound, this.getUpdateAllDelay(this.peers))
3063
+ }
3064
+
3030
3065
  onpeerdestroy() {
3031
3066
  if (--this._active === 0) this.core.checkIfIdle()
3032
3067
  }
@@ -3090,6 +3125,11 @@ module.exports = class Replicator {
3090
3125
  this._notDownloadingTimer = null
3091
3126
  }
3092
3127
 
3128
+ if (this._updateAllBump) {
3129
+ clearTimeout(this._updateAllBump)
3130
+ this._updateAllBump = null
3131
+ }
3132
+
3093
3133
  while (this.peers.length) {
3094
3134
  const peer = this.peers[this.peers.length - 1]
3095
3135
  this.detachFrom(peer.protomux)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hypercore",
3
- "version": "11.33.1",
3
+ "version": "11.33.2",
4
4
  "description": "Hypercore is a secure, distributed append-only log",
5
5
  "main": "index.js",
6
6
  "scripts": {