UNPKG

firelease

Version:

Firebase queue consumer for Node with at-least-once semantics

129 lines 5.8 kB
"use strict"; var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; 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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; var _FireleaseStats_getStuckTasks; Object.defineProperty(exports, "__esModule", { value: true }); exports.FireleaseStats = exports.QueueStats = exports.QueueSourceStats = void 0; const lodash_1 = __importDefault(require("lodash")); function createLeaseTransactionStats() { return { acquired: 0, contended: 0, failed: 0, tries: 0, duration: 0 }; } function rollUpLeaseTransactions(items) { const result = createLeaseTransactionStats(); result.acquired = lodash_1.default.sumBy(items, 'acquired'); result.contended = lodash_1.default.sumBy(items, 'contended'); result.failed = lodash_1.default.sumBy(items, 'failed'); result.tries = lodash_1.default.sumBy(items, 'tries'); const attemptedItems = lodash_1.default.filter(items, countLeaseAttempts); if (attemptedItems.length) result.duration = lodash_1.default.meanBy(attemptedItems, 'duration'); return result; } function countLeaseAttempts(stats) { return stats.acquired + stats.contended + stats.failed; } function exposeGetters(instance, properties) { const prototype = Object.getPrototypeOf(instance); for (const property of properties) { const descriptor = Object.getOwnPropertyDescriptor(prototype, property); Object.defineProperty(instance, property, { ...descriptor, enumerable: true }); } } class QueueSourceStats { constructor(ref) { this.ref = ref; this.connected = false; this.mode = 'safe'; this.size = null; this.healthy = true; this.latency = null; this.leaseTransactions = createLeaseTransactionStats(); } } exports.QueueSourceStats = QueueSourceStats; class QueueStats { constructor(ref, key, sources) { this.ref = ref; this.key = key; this.sources = sources; this.tasksAcquired = 0; exposeGetters(this, ['mode', 'size', 'sizeDelta', 'sizeTimestamp', 'healthy', 'maxLatency', 'leaseTransactions']); } get mode() { const modes = lodash_1.default.uniq(lodash_1.default.map(this.sources, 'mode')); return modes.length === 1 ? modes[0] : 'mixed'; } get size() { const sizes = lodash_1.default.map(this.sources, 'size'); return lodash_1.default.every(sizes, lodash_1.default.isNumber) ? lodash_1.default.sum(sizes) : null; } get sizeDelta() { const deltas = lodash_1.default.map(this.sources, 'sizeDelta'); return lodash_1.default.every(deltas, lodash_1.default.isNumber) ? lodash_1.default.sum(deltas) : undefined; } get sizeTimestamp() { return (0, lodash_1.default)(this.sources).map('sizeTimestamp').filter(lodash_1.default.isNumber).min(); } get healthy() { return lodash_1.default.every(this.sources, source => source.connected && source.healthy); } get maxLatency() { return (0, lodash_1.default)(this.sources).map('latency').max() || 0; } get leaseTransactions() { return rollUpLeaseTransactions(lodash_1.default.map(this.sources, 'leaseTransactions')); } } exports.QueueStats = QueueStats; class FireleaseStats { constructor(getStuckTasks) { _FireleaseStats_getStuckTasks.set(this, void 0); this.queues = []; __classPrivateFieldSet(this, _FireleaseStats_getStuckTasks, getStuckTasks, "f"); exposeGetters(this, [ 'healthy', 'sickQueues', 'sickSources', 'stuckTasks', 'maxLatency', 'leaseTransactions', 'tasksAcquired' ]); } get healthy() { return lodash_1.default.every(this.queues, 'healthy'); } get sickQueues() { return (0, lodash_1.default)(this.queues).reject('healthy').map('key').value(); } get sickSources() { return (0, lodash_1.default)(this.queues) .flatMap(queue => queue.sources) .reject(source => source.connected && source.healthy) .map(source => source.ref) .uniq() .value(); } get stuckTasks() { return __classPrivateFieldGet(this, _FireleaseStats_getStuckTasks, "f").call(this); } get maxLatency() { return (0, lodash_1.default)(this.queues).map('maxLatency').max() || 0; } get leaseTransactions() { return rollUpLeaseTransactions(lodash_1.default.map(this.queues, 'leaseTransactions')); } get tasksAcquired() { return lodash_1.default.sumBy(this.queues, queue => queue.tasksAcquired); } } exports.FireleaseStats = FireleaseStats; _FireleaseStats_getStuckTasks = new WeakMap(); //# sourceMappingURL=stats.js.map