Files
weave-scope/client/app/scripts/utils/web-api-utils.js
2015-11-03 18:27:23 +01:00

147 lines
3.7 KiB
JavaScript

const debug = require('debug')('scope:web-api-utils');
const reqwest = require('reqwest');
const AppActions = require('../actions/app-actions');
const WS_PROTO = window.WS_PROTO || (location.protocol === 'https:' ? 'wss' : 'ws');
const WS_URL = window.WS_URL || WS_PROTO + '://' + location.host + location.pathname.replace(/\/$/, '');
const apiTimerInterval = 10000;
const reconnectTimerInterval = 5000;
const topologyTimerInterval = apiTimerInterval;
const updateFrequency = '5s';
let socket;
let reconnectTimer = 0;
let currentUrl = null;
let currentOptions = null;
let topologyTimer = 0;
let apiDetailsTimer = 0;
function buildOptionsQuery(options) {
if (options) {
return options.reduce(function(query, value, param) {
return `${query}&${param}=${value}`;
}, '');
}
return '';
}
function createWebsocket(topologyUrl, optionsQuery) {
if (socket) {
socket.onclose = null;
socket.onerror = null;
socket.close();
}
socket = new WebSocket(WS_URL + topologyUrl
+ '/ws?t=' + updateFrequency + '&' + optionsQuery);
socket.onopen = function() {
AppActions.openWebsocket();
};
socket.onclose = function() {
clearTimeout(reconnectTimer);
socket = null;
AppActions.closeWebsocket();
debug('Closed websocket to ' + topologyUrl);
reconnectTimer = setTimeout(function() {
createWebsocket(topologyUrl, optionsQuery);
}, reconnectTimerInterval);
};
socket.onerror = function() {
debug('Error in websocket to ' + topologyUrl);
AppActions.receiveError(currentUrl);
};
socket.onmessage = function(event) {
const msg = JSON.parse(event.data);
AppActions.receiveNodesDelta(msg);
};
}
/* keep URLs relative */
function getTopologies(options) {
clearTimeout(topologyTimer);
const optionsQuery = buildOptionsQuery(options);
const url = `api/topology?${optionsQuery}`;
reqwest({
url: url,
success: function(res) {
AppActions.receiveTopologies(res);
topologyTimer = setTimeout(function() {
getTopologies(options);
}, topologyTimerInterval / 2);
},
error: function(err) {
debug('Error in topology request: ' + err);
AppActions.receiveError(url);
topologyTimer = setTimeout(function() {
getTopologies(options);
}, topologyTimerInterval / 2);
}
});
}
function getTopology(topologyUrl, options) {
const optionsQuery = buildOptionsQuery(options);
// only recreate websocket if url changed
if (topologyUrl && (topologyUrl !== currentUrl || currentOptions !== optionsQuery)) {
createWebsocket(topologyUrl, optionsQuery);
currentUrl = topologyUrl;
currentOptions = optionsQuery;
}
}
function getNodeDetails(topologyUrl, nodeId, options) {
const optionsQuery = buildOptionsQuery(options);
if (topologyUrl && nodeId) {
const url = [topologyUrl, '/', encodeURIComponent(nodeId), '?', optionsQuery]
.join('').substr(1);
reqwest({
url: url,
success: function(res) {
AppActions.receiveNodeDetails(res.node);
},
error: function(err) {
debug('Error in node details request: ' + err);
AppActions.receiveError(topologyUrl);
}
});
}
}
function getApiDetails() {
clearTimeout(apiDetailsTimer);
const url = 'api';
reqwest({
url: url,
success: function(res) {
AppActions.receiveApiDetails(res);
apiDetailsTimer = setTimeout(getApiDetails, apiTimerInterval);
},
error: function(err) {
debug('Error in api details request: ' + err);
AppActions.receiveError(url);
apiDetailsTimer = setTimeout(getApiDetails, apiTimerInterval / 2);
}
});
}
module.exports = {
getNodeDetails: getNodeDetails,
getTopologies: getTopologies,
getApiDetails: getApiDetails,
getNodesDelta: getTopology
};