dht-rpc 6.26.1 → 6.26.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.
Files changed (3) hide show
  1. package/index.js +2 -3
  2. package/lib/health.js +38 -26
  3. package/package.json +1 -1
package/index.js CHANGED
@@ -26,7 +26,6 @@ const OLD_NODE = 360 // if an node has been around more than 30 min we consider
26
26
  const DEFAULTS = {
27
27
  concurrency: 10,
28
28
  maxWindow: IO.DEFAULT_MAX_WINDOW,
29
- maxHealthWindow: NetworkHealth.DEFAULT_MAX_HEALTH_WINDOW,
30
29
  maxPingDelay: 10_000
31
30
  }
32
31
 
@@ -44,7 +43,7 @@ class DHT extends EventEmitter {
44
43
  onresponse: this._onresponse.bind(this),
45
44
  ontimeout: this._ontimeout.bind(this)
46
45
  })
47
- this.health = new NetworkHealth(this, opts)
46
+ this.health = new NetworkHealth(this)
48
47
 
49
48
  this.concurrency = opts.concurrency || DEFAULTS.concurrency
50
49
  this.maxPingDelay = opts.maxPingDelay || DEFAULTS.maxPingDelay
@@ -179,7 +178,6 @@ class DHT extends EventEmitter {
179
178
  this._onwakeup()
180
179
  log('Resuming io')
181
180
  await this.io.resume()
182
- this.health.reset()
183
181
  log('Done, dht resumed')
184
182
  this.io.networkInterfaces.on('change', (interfaces) => this._onnetworkchange(interfaces))
185
183
  this.refresh()
@@ -557,6 +555,7 @@ class DHT extends EventEmitter {
557
555
  this._stableTicks = MORE_STABLE_TICKS
558
556
  this._refreshTicks = 1 // triggers a refresh next tick (allow network time to wake up also)
559
557
  this._lastHost = null // clear network cache check
558
+ this.health.reset()
560
559
 
561
560
  if (this.adaptive) {
562
561
  // TODO: re-enable this as soon as we find out why this is over triggering in some edge cases
package/lib/health.js CHANGED
@@ -1,14 +1,14 @@
1
1
  const MAX_HEALTH_WINDOW = 4
2
- const TIMEOUTS_THRESHOLD = 0.5
2
+ const IDLE_THRESHOLD = 4
3
+ const DEGRADED_TIMEOUT_RATE_THRESHOLD = 0.5
3
4
 
4
5
  module.exports = class NetworkHealth {
5
- static DEFAULT_MAX_HEALTH_WINDOW = MAX_HEALTH_WINDOW
6
-
7
- constructor(dht, { maxHealthWindow = MAX_HEALTH_WINDOW } = {}) {
6
+ constructor(dht) {
8
7
  this._dht = dht
9
- this._maxHealthWindow = maxHealthWindow
10
8
  this._window = []
11
9
  this._head = -1
10
+ this._degradedTicks = 0
11
+ this._healthyTicks = 0
12
12
  this.online = true
13
13
  this.degraded = false
14
14
  }
@@ -18,78 +18,90 @@ module.exports = class NetworkHealth {
18
18
  }
19
19
 
20
20
  get previous() {
21
- return this._window[(this._head - 1 + this._maxHealthWindow) % this._maxHealthWindow]
21
+ return this._window[(this._head - 1 + MAX_HEALTH_WINDOW) % MAX_HEALTH_WINDOW]
22
22
  }
23
23
 
24
24
  get newest() {
25
25
  return this._window[this._head]
26
26
  }
27
27
 
28
- get recentResponses() {
28
+ get responses() {
29
29
  if (!this.newest || !this.previous) return 0
30
30
  return this.newest.responses - this.previous.responses
31
31
  }
32
32
 
33
- get recentTimeouts() {
33
+ get timeouts() {
34
34
  if (!this.newest || !this.previous) return 0
35
35
  return this.newest.timeouts - this.previous.timeouts
36
36
  }
37
37
 
38
- get responses() {
39
- if (!this.newest || !this.oldest) return 0
40
- return this.newest.responses - this.oldest.responses
41
- }
42
-
43
- get timeouts() {
44
- if (!this.newest || !this.oldest) return 0
45
- return this.newest.timeouts - this.oldest.timeouts
46
- }
47
-
48
38
  get timeoutsRate() {
49
39
  if (this.timeouts === 0) return 0
50
40
  return this.timeouts / (this.responses + this.timeouts)
51
41
  }
52
42
 
43
+ get cold() {
44
+ return this._window.length < MAX_HEALTH_WINDOW
45
+ }
46
+
53
47
  get idle() {
54
- return this.recentResponses === 0 && this.recentTimeouts === 0
48
+ return this.responses + this.timeouts < IDLE_THRESHOLD
49
+ }
50
+
51
+ get allDegraded() {
52
+ return this._degradedTicks === MAX_HEALTH_WINDOW
53
+ }
54
+
55
+ get allHealthy() {
56
+ return this._healthyTicks === MAX_HEALTH_WINDOW
55
57
  }
56
58
 
57
59
  get stats() {
58
60
  return {
59
61
  online: this.online,
60
62
  degraded: this.degraded,
63
+ cold: this.cold,
61
64
  idle: this.idle,
62
65
  responses: this.responses,
63
66
  timeouts: this.timeouts,
64
- timeoutsRate: this.timeoutsRate,
65
- recentResponses: this.recentResponses,
66
- recentTimeouts: this.recentTimeouts
67
+ timeoutsRate: this.timeoutsRate
67
68
  }
68
69
  }
69
70
 
70
71
  get _tail() {
71
- return (this._head + 1) % this._maxHealthWindow
72
+ return (this._head + 1) % MAX_HEALTH_WINDOW
72
73
  }
73
74
 
74
75
  reset() {
75
76
  this._window = []
76
77
  this._head = -1
78
+ this._degradedTicks = 0
79
+ this._healthyTicks = 0
77
80
  this.online = true
78
81
  this.degraded = false
79
82
  this._dht._online()
80
83
  }
81
84
 
82
85
  update() {
86
+ if (this.oldest?.degraded) this._degradedTicks--
87
+ else if (this.oldest?.degraded === false) this._healthyTicks--
88
+
83
89
  this._head = this._tail
84
90
  this._window[this._head] = {
85
91
  responses: this._dht.stats.requests.responses,
86
92
  timeouts: this._dht.stats.requests.timeouts
87
93
  }
88
94
 
89
- if (this.idle) return
95
+ if (this.cold || this.idle) return
96
+
97
+ this.newest.degraded = this.timeoutsRate > DEGRADED_TIMEOUT_RATE_THRESHOLD
98
+
99
+ if (this.newest.degraded) this._degradedTicks++
100
+ else this._healthyTicks++
90
101
 
91
- this.online = this.recentResponses > 0
92
- this.degraded = this.online && this.timeoutsRate > TIMEOUTS_THRESHOLD
102
+ this.online = this.responses > 0
103
+ if (this.online && this.allDegraded) this.degraded = true
104
+ if (!this.online || this.allHealthy) this.degraded = false
93
105
 
94
106
  if (this.online && !this.degraded) this._dht._online()
95
107
  else if (this.degraded) this._dht._degraded()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dht-rpc",
3
- "version": "6.26.1",
3
+ "version": "6.26.3",
4
4
  "description": "Make RPC calls over a Kademlia based DHT",
5
5
  "main": "index.js",
6
6
  "files": [