@biorate/haproxy
Version:
Haproxy runner
168 lines • 7.3 kB
JavaScript
;
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