hypercore 10.37.21 → 10.37.23

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 (2) hide show
  1. package/lib/replicator.js +46 -11
  2. package/package.json +1 -1
package/lib/replicator.js CHANGED
@@ -37,6 +37,7 @@ const DEFAULT_MAX_INFLIGHT = [16, 512]
37
37
  const SCALE_LATENCY = 50
38
38
  const DEFAULT_SEGMENT_SIZE = 256 * 1024 * 8 // 256 KiB in bits
39
39
  const NOT_DOWNLOADING_SLACK = 20000 + (Math.random() * 20000) | 0
40
+ const MAX_PEERS_UPGRADE = 3
40
41
 
41
42
  const PRIORITY = {
42
43
  NORMAL: 0,
@@ -537,9 +538,11 @@ class Peer {
537
538
  const reopen = isRemote === true && this.remoteOpened === true && this.remoteDownloading === false &&
538
539
  this.remoteUploading === true && this.replicator.downloading === true
539
540
 
540
- if (this.useSession && !reopen) this.replicator._closeSession()
541
-
542
541
  if (this.remoteOpened === false) {
542
+ if (this.useSession) {
543
+ this.replicator._peerSessions--
544
+ this.replicator._closeSessionMaybe()
545
+ }
543
546
  this.replicator._ifAvailable--
544
547
  this.replicator.updateAll()
545
548
  return
@@ -559,6 +562,11 @@ class Peer {
559
562
  if (reopen) {
560
563
  this.replicator._makePeer(this.protomux, this.useSession)
561
564
  }
565
+
566
+ if (this.useSession) {
567
+ this.replicator._peerSessions--
568
+ this.replicator._closeSessionMaybe()
569
+ }
562
570
  }
563
571
 
564
572
  closeIfIdle () {
@@ -1456,6 +1464,8 @@ module.exports = class Replicator {
1456
1464
  this._updatesPending = 0
1457
1465
  this._applyingReorg = null
1458
1466
  this._manifestPeer = null
1467
+ this._hasSession = false
1468
+ this._peerSessions = 0
1459
1469
  this._notDownloadingLinger = notDownloadingLinger
1460
1470
  this._downloadingTimer = null
1461
1471
 
@@ -1658,12 +1668,15 @@ module.exports = class Replicator {
1658
1668
  // instead its more efficient to only call it when the conditions in here change - ie on sync/add/remove peer
1659
1669
  // Do this when we have more tests.
1660
1670
  _checkUpgradeIfAvailable () {
1661
- if (this._ifAvailable > 0 || this._upgrade === null || this._upgrade.refs.length === 0) return
1671
+ if (this._ifAvailable > 0 && this.peers.length < MAX_PEERS_UPGRADE) return
1672
+ if (this._upgrade === null || this._upgrade.refs.length === 0) return
1662
1673
  if (this._hadPeers === false && this.findingPeers > 0) return
1663
1674
 
1675
+ const maxPeers = Math.min(this.peers.length, MAX_PEERS_UPGRADE)
1676
+
1664
1677
  // check if a peer can upgrade us
1665
1678
 
1666
- for (let i = 0; i < this.peers.length; i++) {
1679
+ for (let i = 0; i < maxPeers; i++) {
1667
1680
  const peer = this.peers[i]
1668
1681
 
1669
1682
  if (peer.remoteSynced === false) return
@@ -1690,6 +1703,9 @@ module.exports = class Replicator {
1690
1703
  if (r.inflight.length > 0) return
1691
1704
  }
1692
1705
 
1706
+ // if something is inflight, wait for that first
1707
+ if (this._upgrade.inflight.length > 0) return
1708
+
1693
1709
  // nothing to do, indicate no update avail
1694
1710
 
1695
1711
  const u = this._upgrade
@@ -1771,6 +1787,8 @@ module.exports = class Replicator {
1771
1787
  this._clearRequest(peer, req)
1772
1788
  }
1773
1789
 
1790
+ if (peer.useSession) this._closeSessionMaybe()
1791
+
1774
1792
  this.onpeerupdate(false, peer)
1775
1793
  this.updateAll()
1776
1794
  }
@@ -2243,8 +2261,11 @@ module.exports = class Replicator {
2243
2261
  this._maybeResolveIfAvailableRanges()
2244
2262
  }
2245
2263
 
2246
- _closeSession () {
2247
- this.core.active--
2264
+ _closeSessionMaybe () {
2265
+ if (this._hasSession && this._peerSessions === 0) {
2266
+ this._hasSession = false
2267
+ this.core.active--
2268
+ }
2248
2269
 
2249
2270
  // we were the last active ref, so lets shut things down
2250
2271
  if (this.core.active === 0 && this.core.sessions.length === 0) {
@@ -2263,10 +2284,15 @@ module.exports = class Replicator {
2263
2284
  return this._attached.has(protomux)
2264
2285
  }
2265
2286
 
2287
+ ensureSession () {
2288
+ if (this._hasSession) return
2289
+ this._hasSession = true
2290
+ this.core.active++
2291
+ }
2292
+
2266
2293
  attachTo (protomux, useSession) {
2267
- if (useSession) {
2268
- this.core.active++
2269
- }
2294
+ if (this.core.closed) return
2295
+ if (useSession) this.ensureSession()
2270
2296
 
2271
2297
  const makePeer = this._makePeer.bind(this, protomux, useSession)
2272
2298
 
@@ -2275,12 +2301,15 @@ module.exports = class Replicator {
2275
2301
  protomux.stream.setMaxListeners(0)
2276
2302
  protomux.stream.on('close', this._onstreamclose)
2277
2303
 
2304
+ if (useSession) this._peerSessions++
2278
2305
  this._ifAvailable++
2306
+
2279
2307
  protomux.stream.opened.then((opened) => {
2308
+ if (useSession) this._peerSessions--
2280
2309
  this._ifAvailable--
2281
2310
 
2282
2311
  if (opened && !this.destroyed) makePeer()
2283
- else if (useSession) this._closeSession()
2312
+ else if (useSession) this._closeSessionMaybe()
2284
2313
  this._checkUpgradeIfAvailable()
2285
2314
  })
2286
2315
  }
@@ -2339,6 +2368,12 @@ module.exports = class Replicator {
2339
2368
  const peer = new Peer(replicator, protomux, channel, useSession, this.inflightRange)
2340
2369
  const stream = protomux.stream
2341
2370
 
2371
+ if (useSession) {
2372
+ // session may have been unref'd underneath us
2373
+ replicator.ensureSession()
2374
+ replicator._peerSessions++
2375
+ }
2376
+
2342
2377
  peer.channel.open({
2343
2378
  seeks: true,
2344
2379
  capability: caps.replicate(stream.isInitiator, this.key, stream.handshakeHash)
@@ -2347,7 +2382,7 @@ module.exports = class Replicator {
2347
2382
  return true
2348
2383
 
2349
2384
  function onnochannel () {
2350
- if (useSession) replicator._closeSession()
2385
+ if (useSession) replicator._closeSessionMaybe()
2351
2386
  return false
2352
2387
  }
2353
2388
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hypercore",
3
- "version": "10.37.21",
3
+ "version": "10.37.23",
4
4
  "description": "Hypercore is a secure, distributed append-only log",
5
5
  "main": "index.js",
6
6
  "scripts": {