UNPKG

tribune

Version:

Holy advocate to the Roman Senate, your Tribune will ensure the Consuls have your interests in mind.

90 lines (74 loc) 2.35 kB
const httpMethods = require('http').METHODS; const Endpoint = require('./endpoint'); class Service { constructor(tribune, name) { this._tribune = tribune; this._name = name; this._endpoint = null; this._endpointTags = null; this._endpointUrl = null; this._connectTimeoutId = null; this._requests = []; } request(url, opts, cb = () => {}) { if (url && typeof url === 'object') { cb = opts; opts = url; url = undefined; } if (typeof opts === 'function') { cb = opts; opts = {}; } let attempts = 0; const makeRequest = () => { this.endpoint((err, endpoint) => { if (err) { return cb(err); } opts.baseUrl = endpoint.url; this._tribune._consul._request(url, opts, (err, res) => { if (!err || err && err.code !== 'ENOTFOUND') { return cb(err, res); } attempts += 1; if (attempts > 10) { return cb(err, res); } return makeRequest(); }); }); }; makeRequest(); } endpoint(cb = () => {}) { if (this._endpoint) { return cb(null, this._endpoint); } const timeout = this._tribune._serviceTimeout; if (timeout > 0) { clearTimeout(this._connectTimeoutId); this._connectTimeoutId = setTimeout(() => { throw new Error(`Could not aquire connection to ${this._name} service`); }, timeout); } this._tribune._getConsulServiceEndpoint(this._name, (err, serviceEndpoint) => { if (err || serviceEndpoint) { clearTimeout(this._connectTimeoutId); } if (err) { return cb(err); } if (!serviceEndpoint) { return setTimeout(() => this.endpoint(cb), 300); } this._endpoint = new Endpoint(serviceEndpoint); setTimeout(() => { this._endpoint = null; }, this._tribune._serviceTtl).unref(); cb(null, this._endpoint); }); } } httpMethods.forEach((method) => { Service.prototype[method.toLowerCase()] = function(url, opts, cb) { if (url && typeof url === 'object') { cb = opts; opts = url; url = undefined; } if (typeof opts === 'function') { cb = opts; opts = {}; } opts.method = method; return this.request(url, opts, cb); }; }); module.exports = Service;