UNPKG

node-etcd

Version:

etcd library for node.js (etcd v2 api)

243 lines (209 loc) 7.39 kB
// Generated by CoffeeScript 1.12.7 var CancellationToken, Client, _, deasync, defaultClientOptions, defaultRequestOptions, exports, request, bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; request = require('request'); deasync = require('deasync'); _ = require('lodash'); defaultRequestOptions = { pool: { maxSockets: 100 }, followAllRedirects: true }; defaultClientOptions = { maxRetries: 3 }; CancellationToken = (function() { function CancellationToken(servers1, maxRetries, retries1, errors1) { this.servers = servers1; this.maxRetries = maxRetries; this.retries = retries1 != null ? retries1 : 0; this.errors = errors1 != null ? errors1 : []; this.abort = bind(this.abort, this); this.isAborted = bind(this.isAborted, this); this.setRequest = bind(this.setRequest, this); this.aborted = false; } CancellationToken.prototype.setRequest = function(req) { return this.req = req; }; CancellationToken.prototype.isAborted = function() { return this.aborted; }; CancellationToken.prototype.abort = function() { this.aborted = true; if (this.req != null) { return this.req.abort(); } }; CancellationToken.prototype.cancel = CancellationToken.prototype.abort; CancellationToken.prototype.wasAborted = CancellationToken.prototype.isAborted; return CancellationToken; })(); Client = (function() { function Client(hosts, options1, sslopts) { this.hosts = hosts; this.options = options1; this.sslopts = sslopts; this._shouldRetry = bind(this._shouldRetry, this); this._retry = bind(this._retry, this); this._multiserverHelper = bind(this._multiserverHelper, this); this["delete"] = bind(this["delete"], this); this.patch = bind(this.patch, this); this.post = bind(this.post, this); this.get = bind(this.get, this); this.put = bind(this.put, this); this.execute = bind(this.execute, this); this.syncmsg = {}; } Client.prototype.execute = function(method, options, callback) { var opt, servers, syncResp, token; opt = _.defaults(_.clone(options), this.options, defaultRequestOptions, { method: method }); opt.clientOptions = _.defaults(opt.clientOptions, defaultClientOptions); servers = _.shuffle(this.hosts); token = new CancellationToken(servers, opt.clientOptions.maxRetries); syncResp = this._multiserverHelper(servers, opt, token, callback); if (options.synchronous === true) { return syncResp; } else { return token; } }; Client.prototype.put = function(options, callback) { return this.execute("PUT", options, callback); }; Client.prototype.get = function(options, callback) { return this.execute("GET", options, callback); }; Client.prototype.post = function(options, callback) { return this.execute("POST", options, callback); }; Client.prototype.patch = function(options, callback) { return this.execute("PATCH", options, callback); }; Client.prototype["delete"] = function(options, callback) { return this.execute("DELETE", options, callback); }; Client.prototype._multiserverHelper = function(servers, options, token, callback) { var host, req, reqRespHandler, syncRespHandler; host = _.first(servers); options.url = "" + host + options.path; if (token.isAborted()) { return; } if (host == null) { if (this._shouldRetry(token)) { return this._retry(token, options, callback); } return this._error(token, callback); } reqRespHandler = (function(_this) { return function(err, resp, body) { if (token.isAborted()) { return; } if (_this._isHttpError(err, resp)) { token.errors.push({ server: host, httperror: err, httpstatus: resp != null ? resp.statusCode : void 0, httpbody: resp != null ? resp.body : void 0, response: resp, timestamp: new Date() }); return _this._multiserverHelper(_.drop(servers), options, token, callback); } return _this._handleResponse(err, resp, body, callback); }; })(this); syncRespHandler = (function(_this) { return function(err, body, headers) { options.syncdone = true; return _this.syncmsg = { err: err, body: body, headers: headers }; }; })(this); if (options.synchronous === true) { callback = syncRespHandler; } req = this._doRequest(options, reqRespHandler); token.setRequest(req); if (options.synchronous === true && options.syncdone === void 0) { options.syncdone = false; deasync.loopWhile((function(_this) { return function() { return !options.syncdone; }; })(this)); delete options.syncdone; return this.syncmsg; } else { return req; } }; Client.prototype._doRequest = function(options, reqRespHandler) { return request(options, reqRespHandler); }; Client.prototype._retry = function(token, options, callback) { var doRetry, waitTime; doRetry = (function(_this) { return function() { return _this._multiserverHelper(token.servers, options, token, callback); }; })(this); waitTime = this._waitTime(token.retries); token.retries += 1; return setTimeout(doRetry, waitTime); }; Client.prototype._waitTime = function(retries) { if (process.env.RUNNING_UNIT_TESTS === 'true') { return 1; } /* !pragma no-coverage-next */ return 100 * Math.pow(16, retries); }; Client.prototype._shouldRetry = function(token) { return token.retries < token.maxRetries && this._isPossibleLeaderElection(token.errors); }; Client.prototype._error = function(token, callback) { var error; error = new Error('All servers returned error'); error.errors = token.errors; error.retries = token.retries; if (callback) { return callback(error); } }; Client.prototype._isPossibleLeaderElection = function(errors) { var checkError; checkError = function(e) { var ref, ref1, ref2, ref3; return ((ref = e != null ? (ref1 = e.httperror) != null ? ref1.code : void 0 : void 0) === 'ECONNREFUSED' || ref === 'ECONNRESET') || ((ref2 = e != null ? (ref3 = e.httpbody) != null ? ref3.errorCode : void 0 : void 0) === 300 || ref2 === 301) || /Not current leader/.test(e != null ? e.httpbody : void 0); }; return (errors != null) && _.every(errors, checkError); }; Client.prototype._isHttpError = function(err, resp) { return err || (((resp != null ? resp.statusCode : void 0) != null) && resp.statusCode >= 500); }; Client.prototype._handleResponse = function(err, resp, body, callback) { var error; if (callback == null) { return; } if ((body != null ? body.errorCode : void 0) != null) { error = new Error((body != null ? body.message : void 0) || 'Etcd error'); error.errorCode = body.errorCode; error.error = body; return callback(error, "", (resp != null ? resp.headers : void 0) || {}); } else { return callback(null, body, (resp != null ? resp.headers : void 0) || {}); } }; return Client; })(); exports = module.exports = Client;