This repository has been archived on 2020-03-24. You can view files and clone it, but cannot push or open issues or pull requests.
quay/static/js/services/ping-service.js

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;
}]);