UNPKG

redis-smq

Version:

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

154 lines 5.74 kB
import cronParser from 'cron-parser'; import { MessageDestinationQueueAlreadySetError, MessageDestinationQueueRequiredError, MessageMessageExchangeRequiredError, } from './errors/index.js'; import { MessageState } from './message-state.js'; import { EMessagePropertyStatus, } from './types/index.js'; export class MessageEnvelope { producibleMessage; messageState; status = EMessagePropertyStatus.UNPUBLISHED; destinationQueue = null; consumerGroupId = null; constructor(producibleMessage) { this.producibleMessage = producibleMessage; this.messageState = new MessageState(); const scheduledDelay = this.producibleMessage.getScheduledDelay(); if (scheduledDelay) this.messageState.setNextScheduledDelay(scheduledDelay); } getMessageState() { return this.messageState; } setMessageState(m) { this.messageState = m; return this; } getId() { return this.messageState.getId(); } getSetExpired() { return this.getMessageState().getSetExpired(this.producibleMessage.getTTL(), this.producibleMessage.getCreatedAt()); } getStatus() { return this.status; } setDestinationQueue(queue) { if (this.destinationQueue !== null) { throw new MessageDestinationQueueAlreadySetError(); } this.destinationQueue = queue; return this; } setStatus(s) { this.status = s; return this; } getDestinationQueue() { if (!this.destinationQueue) { throw new MessageDestinationQueueRequiredError(); } return this.destinationQueue; } hasNextDelay() { return this.messageState.hasDelay(); } getNextScheduledTimestamp() { if (this.isSchedulable()) { const messageState = this.getMessageState(); const delay = messageState.getSetNextDelay(); if (delay) { return Date.now() + delay; } const msgScheduledCron = this.producibleMessage.getScheduledCRON(); const cronTimestamp = msgScheduledCron ? cronParser.parseExpression(msgScheduledCron).next().getTime() : 0; const msgScheduledRepeat = this.producibleMessage.getScheduledRepeat(); let repeatTimestamp = 0; if (msgScheduledRepeat) { const newCount = messageState.getMessageScheduledRepeatCount() + 1; if (newCount <= msgScheduledRepeat) { const scheduledRepeatPeriod = this.producibleMessage.getScheduledRepeatPeriod(); const now = Date.now(); if (scheduledRepeatPeriod) { repeatTimestamp = now + scheduledRepeatPeriod; } else { repeatTimestamp = now; } } } if (repeatTimestamp && cronTimestamp) { if (repeatTimestamp < cronTimestamp && messageState.hasScheduledCronFired()) { messageState.incrMessageScheduledRepeatCount(); return repeatTimestamp; } } if (cronTimestamp) { messageState.resetMessageScheduledRepeatCount(); messageState.setMessageScheduledCronFired(true); return cronTimestamp; } if (repeatTimestamp) { messageState.incrMessageScheduledRepeatCount(); return repeatTimestamp; } } return 0; } getExchange() { const exchange = this.producibleMessage.getExchange(); if (!exchange) { throw new MessageMessageExchangeRequiredError(); } return exchange; } toString() { return JSON.stringify(this); } setConsumerGroupId(consumerGroupId) { this.consumerGroupId = consumerGroupId; return this; } getConsumerGroupId() { return this.consumerGroupId; } toJSON() { return { createdAt: this.producibleMessage.getCreatedAt(), ttl: this.producibleMessage.getTTL(), retryThreshold: this.producibleMessage.getRetryThreshold(), retryDelay: this.producibleMessage.getRetryDelay(), consumeTimeout: this.producibleMessage.getConsumeTimeout(), body: this.producibleMessage.getBody(), priority: this.producibleMessage.getPriority(), scheduledCron: this.producibleMessage.getScheduledCRON(), scheduledDelay: this.producibleMessage.getScheduledDelay(), scheduledRepeatPeriod: this.producibleMessage.getScheduledRepeatPeriod(), scheduledRepeat: this.producibleMessage.getScheduledRepeat(), exchange: this.getExchange(), destinationQueue: this.getDestinationQueue(), consumerGroupId: this.getConsumerGroupId(), }; } transfer() { return { ...this.toJSON(), id: this.getId(), messageState: this.getMessageState().toJSON(), status: this.getStatus(), }; } hasRetryThresholdExceeded() { const threshold = this.producibleMessage.getRetryThreshold(); return this.messageState.getAttempts() + 1 >= threshold; } isSchedulable() { return this.hasNextDelay() || this.isPeriodic(); } isPeriodic() { return (this.producibleMessage.getScheduledCRON() !== null || this.producibleMessage.getScheduledRepeat() > 0); } } //# sourceMappingURL=message-envelope.js.map