Commit aed774c44c87b37e617bc05b87adddd2467ba2c5
working on persisting gossip peers
Dominic Tarr committed on 10/9/2016, 1:35:49 AMParent: da63dafc1984303dc09aa3dffc765f2ec017d359
Files changed
plugins/gossip/index.js | changed |
plugins/gossip/schedule.js | changed |
plugins/gossip/index.js | ||
---|---|---|
@@ -7,12 +7,15 @@ | ||
7 | 7 … | var apidoc = require('../../lib/apidocs').gossip |
8 | 8 … | var u = require('../../lib/util') |
9 | 9 … | var ref = require('ssb-ref') |
10 | 10 … | var ping = require('pull-ping') |
11 | -var Stats = require('statistics') | |
11 … | +var stats = require('statistics') | |
12 | 12 … | var isArray = Array.isArray |
13 | 13 … | var Schedule = require('./schedule') |
14 | 14 … | var Init = require('./init') |
15 … | +var AtomicFile = require('atomic-file') | |
16 … | +var path = require('path') | |
17 … | +var deepEqual = require('deep-equal') | |
15 | 18 … | |
16 | 19 … | function isFunction (f) { |
17 | 20 … | return 'function' === typeof f |
18 | 21 … | } |
@@ -44,8 +47,10 @@ | ||
44 | 47 … | var notify = Notify() |
45 | 48 … | var conf = config.gossip || {} |
46 | 49 … | var home = ref.parseAddress(server.getAddress()) |
47 | 50 … | |
51 … | + var stateFile = AtomicFile(path.join(config.path, 'gossip.json')) | |
52 … | + | |
48 | 53 … | //Known Peers |
49 | 54 … | var peers = [] |
50 | 55 … | |
51 | 56 … | function getPeer(id) { |
@@ -90,9 +95,9 @@ | ||
90 | 95 … | p.failure = (p.failure || 0) + 1 |
91 | 96 … | p.stateChange = Date.now() |
92 | 97 … | notify({ type: 'connect-failure', peer: p }) |
93 | 98 … | server.emit('log:info', ['SBOT', p.host+':'+p.port+p.key, 'connection failed', err.message || err]) |
94 | - p.duration.value(0) | |
99 … | + p.duration = stats(p.duration, 0) | |
95 | 100 … | return (cb && cb(err)) |
96 | 101 … | } |
97 | 102 … | else { |
98 | 103 … | p.state = 'connected' |
@@ -133,9 +138,9 @@ | ||
133 | 138 … | if(!f) { |
134 | 139 … | // new peer |
135 | 140 … | addr.source = source |
136 | 141 … | addr.announcers = 1 |
137 | - addr.duration = Stats() | |
142 … | + addr.duration = null | |
138 | 143 … | peers.push(addr) |
139 | 144 … | notify({ type: 'discover', peer: addr, source: source || 'manual' }) |
140 | 145 … | return addr |
141 | 146 … | } |
@@ -199,18 +204,38 @@ | ||
199 | 204 … | //or how many failures there have been. |
200 | 205 … | var since = peer.stateChange |
201 | 206 … | peer.stateChange = Date.now() |
202 | 207 … | if(peer.state === 'connected') //may be "disconnecting" |
203 | - peer.duration.value(peer.stateChange - since) | |
208 … | + peer.duration = stats(peer.duration, peer.stateChange - since) | |
204 | 209 … | peer.state = undefined |
205 | 210 … | notify({ type: 'disconnect', peer: peer }) |
206 | 211 … | server.emit('log:info', ['SBOT', rpc.id, 'disconnect']) |
207 | 212 … | }) |
208 | 213 … | |
209 | 214 … | notify({ type: 'connect', peer: peer }) |
210 | 215 … | }) |
211 | 216 … | |
217 … | + var last | |
218 … | + stateFile.get(function (err, ary) { | |
219 … | + last = ary || [] | |
220 … | + if(Array.isArray(ary)) | |
221 … | + ary.forEach(function (v) { | |
222 … | + delete v.state | |
223 … | + var p = gossip.add(v, 'stored') | |
224 … | + }) | |
225 … | + }) | |
226 … | + | |
227 … | + setInterval(function () { | |
228 … | + if(deepEqual(peers, last)) return | |
229 … | + var copy = JSON.parse(JSON.stringify(peers)) | |
230 … | + copy.forEach(function (e) { | |
231 … | + delete e.state | |
232 … | + }) | |
233 … | + stateFile.set(copy, console.log.bind(console)) | |
234 … | + }, 10*1000) | |
235 … | + | |
212 | 236 … | return gossip |
213 | 237 … | } |
214 | 238 … | } |
215 | 239 … | |
216 | 240 … | |
241 … | + |
plugins/gossip/schedule.js | ||
---|---|---|
@@ -1,11 +1,10 @@ | ||
1 | 1 … | var nonPrivate = require('non-private-ip') |
2 | 2 … | var ip = require('ip') |
3 | 3 … | var onWakeup = require('on-wakeup') |
4 | 4 … | var onNetwork = require('on-change-network') |
5 … | +var hasNetwork = require('has-network') | |
5 | 6 … | |
6 | -var Stats = require('statistics') | |
7 | -var os = require('os') | |
8 | 7 … | var pull = require('pull-stream') |
9 | 8 … | var u = require('../../lib/util') |
10 | 9 … | |
11 | 10 … | function rand(array) { |
@@ -42,10 +41,9 @@ | ||
42 | 41 … | //(i.e. if there is only localhost) |
43 | 42 … | |
44 | 43 … | function isOffline (e) { |
45 | 44 … | if(ip.isLoopback(e.host)) return false |
46 | - var lo = Object.keys(os.networkInterfaces()) | |
47 | - return lo.length === 1 && lo[0] === 'lo' | |
45 … | + return !hasNetwork() | |
48 | 46 … | } |
49 | 47 … | |
50 | 48 … | var isOnline = not(isOffline) |
51 | 49 … | |
@@ -61,20 +59,20 @@ | ||
61 | 59 … | |
62 | 60 … | //select peers which have never been successfully connected to yet, |
63 | 61 … | //but have been tried. |
64 | 62 … | function isInactive (e) { |
65 | - return e.stateChange && e.duration.mean == 0 | |
63 … | + return e.stateChange && (!e.duration || e.duration.mean == 0) | |
66 | 64 … | } |
67 | 65 … | |
68 | 66 … | function isLongterm (e) { |
69 | - return e.ping && e.ping.rtt.mean > 0 | |
67 … | + return e.ping && e.ping.rtt && e.ping.rtt.mean > 0 | |
70 | 68 … | } |
71 | 69 … | |
72 | 70 … | //peers which we can connect to, but are not upgraded. |
73 | 71 … | //select peers which we can connect to, but are not upgraded to LT. |
74 | 72 … | //assume any peer is legacy, until we know otherwise... |
75 | 73 … | function isLegacy (peer) { |
76 | - return peer.duration.mean > 0 && !exports.isLongterm(peer) | |
74 … | + return peer.duration && peer.duration.mean > 0 && !exports.isLongterm(peer) | |
77 | 75 … | } |
78 | 76 … | |
79 | 77 … | function isConnect (e) { |
80 | 78 … | return 'connected' === e.state || 'connecting' === e.state |
@@ -102,9 +100,9 @@ | ||
102 | 100 … | } |
103 | 101 … | |
104 | 102 … | var schedule = exports = module.exports = |
105 | 103 … | function (gossip, config, server) { |
106 | - | |
104 … | +// return | |
107 | 105 … | var min = 60e3, hour = 60*60e3 |
108 | 106 … | |
109 | 107 … | //trigger hard reconnect after suspend or local network changes |
110 | 108 … | onWakeup(gossip.reconnect) |
@@ -128,9 +126,10 @@ | ||
128 | 126 … | gossip.disconnect(peer) |
129 | 127 … | }) |
130 | 128 … | } |
131 | 129 … | |
132 | - select(peers, ts, and(filter, isOnline), opts) | |
130 … | + var selected = select(peers, ts, and(filter, isOnline), opts) | |
131 … | + selected | |
133 | 132 … | .forEach(function (peer) { |
134 | 133 … | gossip.connect(peer) |
135 | 134 … | }) |
136 | 135 … | } |
@@ -140,40 +139,38 @@ | ||
140 | 139 … | function connections () { |
141 | 140 … | if(connecting) return |
142 | 141 … | connecting = true |
143 | 142 … | setTimeout(function () { |
144 | - connecting = false | |
145 | - var ts = Date.now() | |
146 | - var peers = gossip.peers() | |
143 … | + connecting = false | |
144 … | + var ts = Date.now() | |
145 … | + var peers = gossip.peers() | |
147 | 146 … | |
148 | -// if(Math.random() > 0.1) return | |
147 … | + connect(peers, ts, 'attempt', exports.isUnattempted, { | |
148 … | + min: 0, quota: 10, factor: 0, max: 0, groupMin: 0, | |
149 … | + disable: !conf('global', true) | |
150 … | + }) | |
149 | 151 … | |
150 | - connect(peers, ts, 'attempt', exports.isUnattempted, { | |
151 | - min: 0, quota: 10, factor: 0, max: 0, groupMin: 0, | |
152 | - disable: !conf('global', true) | |
153 | - }) | |
152 … | + //quota, groupMin, min, factor, max | |
153 … | + connect(peers, ts, 'retry', exports.isInactive, { | |
154 … | + min: 0, | |
155 … | + quota: 3, factor: 5*60e3, max: 3*60*60e3, groupMin: 5*50e3 | |
156 … | + }) | |
154 | 157 … | |
155 | - //quota, groupMin, min, factor, max | |
156 | - connect(peers, ts, 'retry', exports.isInactive, { | |
157 | - min: 0, | |
158 | - quota: 3, factor: 5*60e3, max: 3*60*60e3, groupMin: 5*50e3 | |
159 | - }) | |
158 … | + connect(peers, ts, 'legacy', exports.isLegacy, { | |
159 … | + quota: 3, factor: 5*min, max: 3*hour, groupMin: 5*min, | |
160 … | + disable: !conf('global', true) | |
161 … | + }) | |
160 | 162 … | |
161 | - connect(peers, ts, 'legacy', exports.isLegacy, { | |
162 | - quota: 3, factor: 5*min, max: 3*hour, groupMin: 5*min, | |
163 … | + connect(peers, ts, 'longterm', exports.isLongterm, { | |
164 … | + quota: 3, factor: 10e3, max: 10*min, groupMin: 5e3, | |
163 | 165 … | disable: !conf('global', true) |
164 | 166 … | }) |
165 | 167 … | |
166 | - connect(peers, ts, 'longterm', exports.isLongterm, { | |
167 | - quota: 3, factor: 10e3, max: 10*min, groupMin: 5e3, | |
168 | - disable: !conf('global', true) | |
169 | - }) | |
168 … | + connect(peers, ts, 'local', exports.isLocal, { | |
169 … | + quota: 3, factor: 2e3, max: 10*min, groupMin: 1e3, | |
170 … | + disable: !conf('local', true) | |
171 … | + }) | |
170 | 172 … | |
171 | - connect(peers, ts, 'local', exports.isLocal, { | |
172 | - quota: 3, factor: 2e3, max: 10*min, groupMin: 1e3, | |
173 | - disable: !conf('local', true) | |
174 | - }) | |
175 | - | |
176 | 173 … | }, 100*Math.random()) |
177 | 174 … | |
178 | 175 … | } |
179 | 176 … | |
@@ -201,4 +198,9 @@ | ||
201 | 198 … | exports.select = select |
202 | 199 … | |
203 | 200 … | |
204 | 201 … | |
202 … | + | |
203 … | + | |
204 … | + | |
205 … | + | |
206 … | + |
Built with git-ssb-web