UNPKG

redis-smq

Version:

A simple high-performance Redis message queue for Node.js.

134 lines 4.55 kB
import * as os from 'os'; import { Runnable, Timer, } from 'redis-smq-common'; import { redisKeys } from '../../../common/redis-keys/redis-keys.js'; import { eventBusPublisher } from './event-bus-publisher.js'; const cpuUsageStatsRef = { cpuUsage: process.cpuUsage(), time: process.hrtime(), }; function cpuUsage() { const currentTimestamp = process.hrtime(); const currentCPUUsage = process.cpuUsage(); const timestampDiff = process.hrtime(cpuUsageStatsRef.time); const cpuUsageDiff = process.cpuUsage(cpuUsageStatsRef.cpuUsage); cpuUsageStatsRef.time = currentTimestamp; cpuUsageStatsRef.cpuUsage = currentCPUUsage; const hrtime = (time) => { return time[0] * 1e3 + time[1] / 1e6; }; const usageTime = (time) => { return time / 1000; }; return { percentage: ((usageTime(cpuUsageDiff.user + cpuUsageDiff.system) / hrtime(timestampDiff)) * 100).toFixed(1), ...cpuUsageDiff, }; } export class ConsumerHeartbeat extends Runnable { static heartbeatTTL = 10 * 1000; timer; keyConsumerHeartbeat; consumer; logger; redisClient; constructor(consumer, redisClient, logger, eventBus) { super(); this.consumer = consumer; this.logger = logger; this.redisClient = redisClient; if (eventBus) { eventBusPublisher(this, eventBus, this.logger); } const { keyConsumerHeartbeat } = redisKeys.getConsumerKeys(consumer.getId()); this.keyConsumerHeartbeat = keyConsumerHeartbeat; this.timer = new Timer(); this.timer.on('error', (err) => { this.emit('consumerHeartbeat.error', err); }); } getLogger() { return this.logger; } getPayload() { const timestamp = Date.now(); return { timestamp, data: { ram: { usage: process.memoryUsage(), free: os.freemem(), total: os.totalmem(), }, cpu: cpuUsage(), }, }; } beat() { const redisClient = this.redisClient.getInstance(); if (redisClient instanceof Error) { this.emit('consumerHeartbeat.error', redisClient); return void 0; } const heartbeatPayload = this.getPayload(); const consumerId = this.consumer.getId(); const timestamp = Date.now(); const heartbeatPayloadStr = JSON.stringify(heartbeatPayload); redisClient.set(this.keyConsumerHeartbeat, heartbeatPayloadStr, { expire: { mode: 'PX', value: ConsumerHeartbeat.heartbeatTTL, }, }, (err) => { if (err) this.emit('consumerHeartbeat.error', err); else { this.emit('consumerHeartbeat.heartbeat', consumerId, timestamp, heartbeatPayload); this.timer.setTimeout(() => this.beat(), 1000); } }); } goingUp() { return super.goingUp().concat([ (cb) => { const cleanUp = () => { this.removeListener('consumerHeartbeat.heartbeat', onHeartbeat); this.removeListener('consumerHeartbeat.error', onError); }; const onError = (err) => { cleanUp(); cb(err); }; const onHeartbeat = () => { cleanUp(); cb(); }; this.once('consumerHeartbeat.heartbeat', onHeartbeat); this.once('consumerHeartbeat.error', onError); this.beat(); }, ]); } goingDown() { return [ (cb) => { this.timer.reset(); const redisClient = this.redisClient.getInstance(); if (redisClient instanceof Error) return cb(); redisClient.del(this.keyConsumerHeartbeat, () => cb()); }, ].concat(super.goingDown()); } static isConsumerAlive(redisClient, consumerId, cb) { const { keyConsumerHeartbeat } = redisKeys.getConsumerKeys(consumerId); redisClient.get(keyConsumerHeartbeat, (err, heartbeat) => { if (err) cb(err); else cb(null, !!heartbeat); }); } } //# sourceMappingURL=consumer-heartbeat.js.map