UNPKG

@biorate/haproxy

Version:
168 lines 7.3 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __exportStar = (this && this.__exportStar) || function(m, exports) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var _HaproxyConnector_configs; Object.defineProperty(exports, "__esModule", { value: true }); exports.HaproxyConnector = void 0; const HAProxy = require("haproxy"); const tools_1 = require("@biorate/tools"); const inversion_1 = require("@biorate/inversion"); const connector_1 = require("@biorate/connector"); const tools_2 = require("@biorate/tools"); const os_1 = require("os"); const fs_1 = require("fs"); const util_1 = require("util"); const errors_1 = require("./errors"); __exportStar(require("./errors"), exports); __exportStar(require("./interfaces"), exports); let HaproxyConnector = class HaproxyConnector extends connector_1.Connector { constructor() { super(...arguments); _HaproxyConnector_configs.set(this, new WeakMap()); this.namespace = 'Haproxy'; } async connect(config) { let connection; try { this.cleanup(config); const cfgFile = this.createConfig(config); connection = new HAProxy(this.path(config, 'sock'), { pidFile: this.path(config, 'pid'), config: cfgFile, }); for (const method of [ 'start', 'stop', 'softstop', 'reload', 'verify', 'running', 'clear', 'disable', 'enable', 'pause', 'resume', 'errors', 'weight', 'maxconn', 'ratelimit', 'compression', 'info', 'session', 'stat', ]) connection[method] = (0, util_1.promisify)(connection[method].bind(connection)); await connection.start(); await this.readiness(connection, config); __classPrivateFieldGet(this, _HaproxyConnector_configs, "f").set(connection, config); } catch (e) { throw new errors_1.HaproxyCantConnectError(e); } return connection; } async readiness(connection, config) { var _a, _b, _c, _d, _e, _f; if ((_b = (_a = config === null || config === void 0 ? void 0 : config.readiness) === null || _a === void 0 ? void 0 : _a.nodes) === null || _b === void 0 ? void 0 : _b.length) { let i = 0; w: while (true) { const stats = await connection.stat(); for (const stat of stats) { if (!config.readiness.nodes.includes(stat.svname)) continue; if (stat.status === 'UP') break w; } console.debug(`Attempt to connect to Haproxy: [%s]`, config.name); await tools_1.timer.wait((_d = (_c = config === null || config === void 0 ? void 0 : config.readiness) === null || _c === void 0 ? void 0 : _c.delay) !== null && _d !== void 0 ? _d : 1000); ++i; if ((_f = i > ((_e = config === null || config === void 0 ? void 0 : config.readiness) === null || _e === void 0 ? void 0 : _e.retries)) !== null && _f !== void 0 ? _f : 1) throw new errors_1.HaproxyConnectionTimeoutError(config.name); } } } path(config, ext) { return tools_2.path.create((0, os_1.tmpdir)(), `${config.name}.haproxy.${ext}`); } cleanup(config) { try { (0, fs_1.unlinkSync)(this.path(config, 'sock')); } catch (_a) { } try { (0, fs_1.unlinkSync)(this.path(config, 'pid')); } catch (_b) { } try { (0, fs_1.unlinkSync)(this.path(config, 'config')); } catch (_c) { } } createConfig(config) { let data = ''; const file = this.path(config, 'config'); for (const header in config.config) { data += header + os_1.EOL; if (Array.isArray(config.config[header])) for (const field of config.config[header]) data += ' ' + field + os_1.EOL; else for (const field in config.config[header]) data += ' ' + field + ' ' + config.config[header][field] + os_1.EOL; } data = data.replace('{{stat_socket_path}}', this.path(config, 'sock')); (0, fs_1.writeFileSync)(file, data, 'utf-8'); if (config.debug) console.debug(`Haproxy [${config.name}] config:${os_1.EOL}`, data); return file; } async destructor() { for (const [, connection] of this.connections) { try { await connection.stop(); this.cleanup(__classPrivateFieldGet(this, _HaproxyConnector_configs, "f").get(connection)); } catch (e) { console.error(e); } } } }; _HaproxyConnector_configs = new WeakMap(); __decorate([ (0, inversion_1.kill)(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", Promise) ], HaproxyConnector.prototype, "destructor", null); HaproxyConnector = __decorate([ (0, inversion_1.injectable)() ], HaproxyConnector); exports.HaproxyConnector = HaproxyConnector; //# sourceMappingURL=index.js.map