@imqueue/core
Version:
Simple JSON-based messaging queue for inter service communication
460 lines (459 loc) • 11.1 kB
TypeScript
import { EventEmitter } from 'events';
import { IMessageQueue, JsonObject, IMQOptions, IMQMode, EventMap } from '.';
export declare const DEFAULT_IMQ_OPTIONS: IMQOptions;
export declare const IMQ_SHUTDOWN_TIMEOUT: number;
/**
* Returns SHA1 hash sum of the given string
*
* @param {string} str
* @returns {string}
*/
export declare function sha1(str: string): string;
/**
* Returns random integer between given min and max
*
* @param {number} min
* @param {number} max
* @returns {number}
*/
export declare function intrand(min: number, max: number): number;
/**
* Compress given data and returns binary string
*
* @param {any} data
* @returns {string}
*/
export declare function pack(data: any): string;
/**
* Decompress binary string and returns plain data
*
* @param {string} data
* @returns {any}
*/
export declare function unpack(data: string): any;
/**
* Class RedisQueue
* Implements simple messaging queue over redis.
*/
export declare class RedisQueue extends EventEmitter<EventMap> implements IMessageQueue {
name: string;
private readonly mode;
[name: string]: any;
/**
* Writer connections collection
*
* @type {{}}
*/
private static writers;
/**
* Watcher connections collection
*
* @type {{}}
*/
private static watchers;
/**
* @event message (message: JsonObject, id: string, from: string)
*/
/**
* This queue instance options
*
* @type {IMQOptions}
*/
options: IMQOptions;
/**
* Reader connection associated with this queue instance
*
* @type {IRedisClient}
*/
private reader?;
/**
* Channel connection associated with this queue instance
* Specially designed for client subscriptions to server-emitted events
*
* @type {IRedisClient}
*/
private subscription?;
/**
* Channel name for subscriptions
*
* @type {string}
*/
private subscriptionName?;
/**
* Init state for this queue instance
*
* @type {boolean}
*/
private initialized;
/**
* Signals if the queue was destroyed
*
* @type {boolean}
*/
private destroyed;
/**
* True if the current instance owns a watcher connection, false otherwise
*
* @type {boolean}
*/
private watchOwner;
/**
* Signals initialization state
*
* @type {boolean}
*/
private signalsInitialized;
/**
* Will store check interval reference
*/
private safeCheckInterval;
/**
* This queue instance unique key (identifier), for internal use
*/
private readonly redisKey;
/**
* LUA scripts for redis
*
* @type {{moveDelayed: {code: string}}}
*/
private scripts;
/**
* Serializes given data object into string
*
* @param {any} data
* @returns {string}
*/
private readonly pack;
/**
* Deserialize string data into object
*
* @param {string} data
* @returns {any}
*/
private readonly unpack;
/**
* @constructor
* @param {string} name
* @param {IMQOptions} [options]
* @param {IMQMode} [mode]
*/
constructor(name: string, options?: Partial<IMQOptions>, mode?: IMQMode);
/**
* Creates a subscription channel over redis and sets up channel
* data read handler
*
* @param {string} channel
* @param {(data: JsonObject) => any} handler
* @return {Promise<void>}
*/
subscribe(channel: string, handler: (data: JsonObject) => any): Promise<void>;
/**
* Closes subscription channel
*
* @return {Promise<void>}
*/
unsubscribe(): Promise<void>;
/**
* Publishes a message to this queue subscription channel for currently
* subscribed clients.
*
* If toName specified will publish to PubSub with a different name. This
* can be used to implement broadcasting some messages to other subscribers
* on other PubSub channels.
*
* @param {string} [toName]
* @param {JsonObject} data
*/
publish(data: JsonObject, toName?: string): Promise<void>;
/**
* Initializes and starts current queue routines
*
* @returns {Promise<RedisQueue>}
*/
start(): Promise<RedisQueue>;
/**
* Sends a given message to a given queue (by name)
*
* @param {string} toQueue
* @param {JsonObject} message
* @param {number} [delay]
* @param {(err: Error) => void} [errorHandler]
* @returns {Promise<RedisQueue>}
*/
send(toQueue: string, message: JsonObject, delay?: number, errorHandler?: (err: Error) => void): Promise<string>;
/**
* Stops current queue routines
*
* @returns {Promise<RedisQueue>}
*/
stop(): Promise<RedisQueue>;
/**
* Gracefully destroys this queue
*
* @returns {Promise<void>}
*/
destroy(): Promise<void>;
/**
* Clears queue data in redis;
*
* @returns {Promise<void>}
*/
clear(): Promise<RedisQueue>;
/**
* Returns true if publisher mode is enabled on this queue, false otherwise.
*
* @return {boolean}
*/
isPublisher(): boolean;
/**
* Returns true if worker mode is enabled on this queue, false otherwise.
*
* @return {boolean}
*/
isWorker(): boolean;
/**
* Writer connection associated with this queue instance
*
* @type {IRedisClient}
*/
private get writer();
/**
* Writer connection setter.
*
* @param {IRedisClient} conn
*/
private set writer(value);
/**
* Watcher connection instance associated with this queue instance
*
* @type {IRedisClient}
*/
private get watcher();
/**
* Watcher setter sets the watcher connection property for this
* queue instance
*
* @param {IRedisClient} conn
*/
private set watcher(value);
/**
* Logger instance associated with the current queue instance
* @type {ILogger}
*/
private get logger();
/**
* Return a lock key for watcher connection
*
* @access private
* @returns {string}
*/
private get lockKey();
/**
* Returns current queue key
*
* @access private
* @returns {string}
*/
private get key();
/**
* Destroys watcher channel
*
* @access private
*/
private destroyWatcher;
/**
* Destroys writer channel
*
* @access private
*/
private destroyWriter;
/**
* Establishes a given connection channel by its name
*
* @access private
* @param {RedisConnectionChannel} channel
* @param {IMQOptions} options
* @param {any} context
* @returns {Promise<IRedisClient>}
*/
private connect;
/**
* Builds and returns redis reconnection strategy
*
* @param {RedisQueue} context
* @returns {() => (number | void | null)}
* @private
*/
private retryStrategy;
/**
* Builds and returns connection ready state handler
*
* @access private
* @param {RedisQueue} context
* @param {RedisConnectionChannel} channel
* @param {(...args: any[]) => void} resolve
* @return {() => Promise<void>}
*/
private onReadyHandler;
/**
* Generates channel name
*
* @param {string} contextName
* @param {string} prefix
* @param {RedisConnectionChannel} name
* @return {string}
*/
private getChannelName;
/**
* Builds and returns connection error handler
*
* @access private
* @param {RedisQueue} context
* @param {RedisConnectionChannel} channel
* @param {(...args: any[]) => void} reject
* @return {(err: Error) => void}
*/
private onErrorHandler;
/**
* Builds and returns redis connection close handler
*
* @access private
* @param {RedisQueue} context
* @param {RedisConnectionChannel} channel
* @return {(...args: any[]) => any}
*/
private onCloseHandler;
/**
* Processes given redis-queue message
*
* @access private
* @param {[any, any]} msg
* @returns {RedisQueue}
*/
private process;
/**
* Returns the number of established watcher connections on redis
*
* @access private
* @returns {Promise<number>}
*/
private watcherCount;
/**
* Processes delayed a message by its given redis key
*
* @access private
* @param {string} key
* @returns {Promise<void>}
*/
private processDelayed;
/**
* Watch routine
*
* @access private
* @return {Promise<void>}
*/
private processWatch;
/**
* Process given keys from a message queue
*
* @access private
* @param {string[]} keys
* @param {number} now
* @return {Promise<void>}
*/
private processKeys;
/**
* Watch message processor
*
* @access private
* @param {...any[]} args
* @return {Promise<void>}
*/
private onWatchMessage;
/**
* Clears safe check interval
*
* @access private
*/
private cleanSafeCheckInterval;
/**
* Setups watch a process on delayed messages
*
* @access private
* @returns {RedisQueue}
*/
private watch;
/**
* Cleans up orphaned keys from redis
*
* @access private
* @returns {Promise<RedisQueue | undefined>}
*/
private processCleanup;
/**
* Unreliable but fast way of message handling by the queue
*/
private readUnsafe;
/**
* Reliable but slow method of message handling by message queue
*/
private readSafe;
/**
* Initializes a read process on the redis message queue
*
* @returns {RedisQueue}
*/
private read;
/**
* Checks if the watcher connection is locked
*
* @access private
* @returns {Promise<boolean>}
*/
private isLocked;
/**
* Locks watcher connection
*
* @access private
* @returns {Promise<boolean>}
*/
private lock;
/**
* Unlocks watcher connection
*
* @access private
* @returns {Promise<boolean>}
*/
private unlock;
/**
* Emits error
*
* @access private
* @param {string} eventName
* @param {string} message
* @param {Error} err
*/
private emitError;
/**
* Acquires an owner for watcher connection to this instance of the queue
*
* @returns {Promise<void>}
*/
private ownWatch;
/**
* This method returns watcher lock resolver function
*
* @access private
* @param {(...args: any[]) => void} resolve
* @param {(...args: any[]) => void} reject
* @return {() => Promise<any>}
*/
private watchLockResolver;
/**
* Initializes a single watcher connection across all queues with the same
* prefix.
*
* @returns {Promise<void>}
*/
private initWatcher;
}