-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
97 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,54 +1,54 @@ | ||
const dns = require('dns'); | ||
const http = require('http'); | ||
/** | ||
* DNS is usually a better way to test connectivity than HTTP | ||
* HTTP is used regardless due to a bug in Electron/Chromium | ||
* @see https://github.com/electron/electron/issues/2299 | ||
*/ | ||
const ping = require('./ping/http'); // require('./ping/dns') | ||
const onetime = require('onetime'); | ||
const status = require('./status'); | ||
|
||
const HOST = {method: 'HEAD', host: 'google.com', path: '/'}; | ||
const INTERVAL = 3000; | ||
const MAX_MS = 800; | ||
// How many SLOW in a row to conclude | ||
const SLOW_ATTEMPTS = 5; | ||
const PING_INTERVAL = 3000; | ||
const SAMPLE_SIZE = 5; | ||
|
||
let last; | ||
let count = 0; | ||
let samples = []; | ||
|
||
exports.monitor = function(cb) { | ||
setInterval(function() { check(cb); }, INTERVAL); | ||
setInterval(function() { check(cb); }, PING_INTERVAL); | ||
check(cb); | ||
}; | ||
|
||
exports.getMode = function() { | ||
return ping.NAME; | ||
}; | ||
|
||
function check(cb) { | ||
ping(function(err, ms) { | ||
const curr = getStatus(err, ms); | ||
const start = Date.now(); | ||
ping.run(onetime(function(err) { | ||
record(err ? Infinity : Date.now() - start); | ||
const curr = getStatus(); | ||
if (curr !== last) { | ||
last = curr; | ||
cb(curr); | ||
} | ||
}); | ||
})); | ||
} | ||
|
||
function getStatus(err, ms) { | ||
if (err) return status.OFFLINE; | ||
if (ms <= MAX_MS) { | ||
count = 0; | ||
return status.ONLINE; | ||
function record(ms) { | ||
samples.push(ms); | ||
if (samples.length > SAMPLE_SIZE) { | ||
samples.shift(); | ||
} | ||
if (++count >= SLOW_ATTEMPTS || !last) { | ||
return status.SLOW; | ||
} | ||
return last; | ||
} | ||
|
||
function ping(done) { | ||
// Using DNS is not good enough because it has caching | ||
// Using native ping I don't like because it means more running processes | ||
const start = Date.now(); | ||
const req = http.request(HOST); | ||
req.on('response', function(res) { | ||
// Flush | ||
res.resume(); | ||
done(null, Date.now() - start); | ||
}) | ||
req.on('error', done); | ||
req.end(); | ||
function getStatus() { | ||
const sorted = samples.concat().sort(function(a, b) { | ||
return a - b; | ||
}); | ||
// Use median rather than average to reduce the impact of outliers | ||
const mid = Math.ceil((sorted.length - 1) / 2); | ||
const median = sorted[mid]; | ||
if (median === Infinity) return status.OFFLINE; | ||
if (median < ping.THRESHOLD) return status.ONLINE; | ||
return status.SLOW; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/** | ||
* DNS is usually a better way to test connectivity as it relies on less layers and is ligther | ||
* Electron/Chromium has a bug, with no connection the callback is never called | ||
* and Chromium logs an error to the console without any way to catch it | ||
* @see https://github.com/electron/electron/issues/2299 | ||
*/ | ||
const dns = require('dns'); | ||
|
||
// Google DNS + OpenDNS | ||
const IPS = ['8.8.8.8', '8.8.4.4', '208.67.222.222', '208.67.220.220']; | ||
const HOST = 'google.com'; | ||
|
||
dns.setServers(IPS); | ||
|
||
exports.THRESHOLD = 300; | ||
|
||
exports.NAME = 'DNS'; | ||
|
||
exports.run = function(done) { | ||
// dns.lookup() won't work because OS caches results | ||
dns.resolve(HOST, done); | ||
// TODO: How to avoid request stacking? | ||
setTimeout(exports.THRESHOLD, done); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
const http = require('http'); | ||
|
||
const HOST = {method: 'HEAD', host: 'google.com', path: '/'}; | ||
|
||
// Natually takes longer than dns queries | ||
exports.THRESHOLD = 800; | ||
|
||
exports.NAME = 'HTTP'; | ||
|
||
exports.run = function(done) { | ||
const req = http.request(HOST); | ||
req.on('response', function(res) { | ||
res.resume(); | ||
done(); | ||
}); | ||
// Don't let it take ages so they don't stack | ||
req.setTimeout(exports.THRESHOLD, function () { | ||
req.abort(); | ||
done(); | ||
}); | ||
req.on('error', done); | ||
req.end(); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters