UNPKG

do-node-balancer

Version:
87 lines (77 loc) 1.92 kB
const _ = require('lodash'); module.exports = ({ joi, doTags, doRequest, opts }) => { const servers = {}; const doResp = joi.object().keys({ droplets: joi.array().min(1).required(), }); function updateServers() { doTags.forEach((tag) => { doRequest.getDropletsByTag(tag) .then(body => doResp.validate(body, { allowUnknown: true })) .then(({ droplets }) => droplets .map(droplet => _.get(droplet, 'networks.v4', null)) .filter(nets => Array.isArray(nets)) .map(nets => nets .filter(net => net instanceof Object) .find(net => net.type === 'public'), ) .filter(net => net.ip_address) .map(net => ({ ...net, failCount: 0, })), ) .then((result) => { if (result) { servers[tag] = result; } else { throw new Error('No Result'); } }) .catch(err => console.log('error ', err)); }); } if (opts.doUpdateTime > 0) { updateServers(); setInterval(updateServers, opts.doUpdateTime); } function getServer(tags) { if (!Array.isArray(tags)) { return null; } return _.sample( _.intersection( ...tags .map(tag => ( servers[tag] && servers[tag].map(taggedServer => taggedServer.ip_address)) || [], ) .map(addrs => addrs || []), ), ) || null; } function getServerList() { return servers; } function reportFailure(target) { if (!(target instanceof Object && target.tags && Array.isArray(target.tags) && target.host)) { return; } target.tags.forEach((tag) => { const suspects = servers[tag]; const crimeIndex = _.findIndex(suspects, ['ip_address', target.host]); if (crimeIndex > 0) { suspects[crimeIndex].failCount += 1; if (suspects[crimeIndex].failCount > opts.maxFailCount) { suspects.splice(crimeIndex, 1); } } }); } return { getServer, getServerList, reportFailure, updateServers, }; };