all files / src/ service_discovery.js

93.33% Statements 28/30
91.67% Branches 11/12
100% Functions 5/5
92.86% Lines 26/28
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58    32×           16×     22× 15×       22× 22× 22× 22×   10× 10×                   10× 10×         22× 10× 10× 10×     12×        
 
const dns = require('dns');
const retry = require('retry-promise').default;
const log = require('debug')('pw:service_discovery');
 
function chaosMonkeyIsMad() {
    return process.env.SERVICE_CALL_CHAOS_PERCENT
        && Math.random() < process.env.SERVICE_CALL_CHAOS_PERCENT;
}
 
const Services = {
 
    discover(serviceHostname, retryOptions) {
        if (!serviceHostname) {
            return Promise.reject(new Error('serviceHostname is required.'));
        }
 
        const doLookup = () => this.lookup(serviceHostname);
        return retry(retryOptions, doLookup);
    },
 
    lookup(hostname) {
        const name = this.alterServiceName(hostname);
        return new Promise((resolve, reject) => {
            dns.resolve(name, 'SRV', (err, res) => {
                if (err) return reject(err);
 
                Eif (res.length > 0) {
                    return resolve(this.formatHostResult(res));
                }
 
                log('service-discovery fail %s worker DNS.', name);
                return reject(new Error(`service discovery fail; ${name}`));
            });
        });
    },
 
    formatHostResult(results) {
        const host = results[0];
        if (chaosMonkeyIsMad()) {
            return `http://${host.name}.notexist:${host.port}`;
        }
        return `http://${host.name}:${host.port}`;
    },
 
    alterServiceName(serviceHostname) {
        if (chaosMonkeyIsMad()) {
            const url = `${serviceHostname}.super.fake`;
            log('CHAOS! Resolved %s to %s', serviceHostname, url);
            return url;
        }
 
        return serviceHostname;
    },
};
 
module.exports = Services;