99 lines
2.5 KiB
JavaScript
99 lines
2.5 KiB
JavaScript
/**
|
|
* Service which pings an endpoint URL and estimates the latency to it.
|
|
*/
|
|
angular.module('quay').factory('PingService', [function() {
|
|
var pingService = {};
|
|
var pingCache = {};
|
|
|
|
var invokeCallback = function($scope, pings, callback) {
|
|
if (pings[0] == -1) {
|
|
setTimeout(function() {
|
|
$scope.$apply(function() {
|
|
callback(-1, false, -1);
|
|
});
|
|
}, 0);
|
|
return;
|
|
}
|
|
|
|
var sum = 0;
|
|
for (var i = 0; i < pings.length; ++i) {
|
|
sum += pings[i];
|
|
}
|
|
|
|
// Report the average ping.
|
|
setTimeout(function() {
|
|
$scope.$apply(function() {
|
|
callback(Math.floor(sum / pings.length), true, pings.length);
|
|
});
|
|
}, 0);
|
|
};
|
|
|
|
var reportPingResult = function($scope, url, ping, callback) {
|
|
// Lookup the cached ping data, if any.
|
|
var cached = pingCache[url];
|
|
if (!cached) {
|
|
cached = pingCache[url] = {
|
|
'pings': []
|
|
};
|
|
}
|
|
|
|
// If an error occurred, report it and done.
|
|
if (ping < 0) {
|
|
cached['pings'] = [-1];
|
|
invokeCallback($scope, [-1], callback);
|
|
return;
|
|
}
|
|
|
|
// Otherwise, add the current ping and determine the average.
|
|
cached['pings'].push(ping);
|
|
|
|
// Invoke the callback.
|
|
invokeCallback($scope, cached['pings'], callback);
|
|
|
|
// Schedule another check if we've done less than three.
|
|
if (cached['pings'].length < 3) {
|
|
setTimeout(function() {
|
|
pingUrlInternal($scope, url, callback);
|
|
}, 1000);
|
|
}
|
|
};
|
|
|
|
var pingUrlInternal = function($scope, url, callback) {
|
|
var path = url + '?cb=' + (Math.random() * 100);
|
|
var start = new Date();
|
|
var xhr = new XMLHttpRequest();
|
|
xhr.onerror = function() {
|
|
reportPingResult($scope, url, -1, callback);
|
|
};
|
|
|
|
xhr.onreadystatechange = function () {
|
|
if (xhr.readyState === xhr.HEADERS_RECEIVED) {
|
|
if (xhr.status != 200) {
|
|
reportPingResult($scope, url, -1, callback);
|
|
return;
|
|
}
|
|
|
|
var ping = (new Date() - start);
|
|
reportPingResult($scope, url, ping, callback);
|
|
}
|
|
};
|
|
|
|
xhr.open("GET", path);
|
|
xhr.send(null);
|
|
};
|
|
|
|
pingService.pingUrl = function($scope, url, callback) {
|
|
if (pingCache[url]) {
|
|
invokeCallback($scope, pingCache[url]['pings'], callback);
|
|
return;
|
|
}
|
|
|
|
// Note: We do each in a callback after 1s to prevent it running when other code
|
|
// runs (which can skew the results).
|
|
setTimeout(function() {
|
|
pingUrlInternal($scope, url, callback);
|
|
}, 1000);
|
|
};
|
|
|
|
return pingService;
|
|
}]);
|