redis-smq
Version:
A simple high-performance Redis message queue for Node.js.
83 lines • 4.2 kB
JavaScript
import { withRedisClient } from 'redis-smq-common';
import { QueueMessagesStorage } from './queue-messages-storage.js';
export class QueueMessagesStorageList extends QueueMessagesStorage {
constructor(redisClient) {
super(redisClient);
this.logger.debug(`${this.constructor.name} initialized`);
}
count(redisKey, cb) {
this.logger.debug(`Counting items in list ${redisKey}`);
withRedisClient(this.redisClient, (client, cb) => {
this.logger.debug(`Executing LLEN on ${redisKey}`);
client.llen(redisKey, (err, count) => {
if (err) {
this.logger.error(`LLEN failed for ${redisKey}: ${err.message}`);
return cb(err);
}
this.logger.debug(`${redisKey} contains ${count} items`);
return cb(null, count);
});
}, cb);
}
fetchItems(redisKey, pageParams, cb) {
const { offsetStart, offsetEnd } = pageParams;
this.logger.debug(`Fetching items from ${redisKey} range [${offsetStart}:${offsetEnd}]`);
withRedisClient(this.redisClient, (client, cb) => {
client.lrange(redisKey, offsetStart, offsetEnd, (err, items) => {
if (err) {
this.logger.error(`LRANGE operation failed: ${err.message}`);
return cb(err);
}
const itemCount = items ? items.length : 0;
this.logger.debug(`Got ${itemCount} items from ${redisKey}`);
return cb(null, items || []);
});
}, cb);
}
fetchAllItems(redisKey, cb) {
const chunkSize = 100;
this.logger.debug(`Fetching all items with chunk size ${chunkSize}`);
withRedisClient(this.redisClient, (client, cb) => {
this.logger.debug(`Executing LLEN on ${redisKey} to determine total length`);
client.llen(redisKey, (err, reply) => {
if (err) {
this.logger.error(`LLEN operation failed: ${err.message}`);
return cb(err);
}
const totalLength = Number(reply);
this.logger.debug(`${redisKey} total length: ${totalLength}`);
if (totalLength === 0) {
this.logger.debug(`List ${redisKey} is empty, returning empty array`);
return cb(null, []);
}
const allItems = [];
const totalChunks = Math.ceil(totalLength / chunkSize);
this.logger.debug(`Processing ${totalChunks} chunks for list ${redisKey}`);
const processChunk = (offset, chunkIndex = 1) => {
if (offset >= totalLength) {
this.logger.debug(`Completed all chunks, returning ${allItems.length} items`);
return cb(null, allItems);
}
const end = Math.min(offset + chunkSize - 1, totalLength - 1);
this.logger.debug(`Chunk ${chunkIndex}/${totalChunks}: range [${offset}:${end}]`);
client.lrange(redisKey, offset, end, (err, items) => {
if (err) {
this.logger.error(`LRANGE operation failed for chunk ${chunkIndex}: ${err.message}`);
return cb(err);
}
if (!items || items.length === 0) {
this.logger.debug(`Chunk ${chunkIndex} is empty, returning ${allItems.length} items`);
return cb(null, allItems);
}
const chunkItemCount = items.length;
allItems.push(...items);
this.logger.debug(`Added ${chunkItemCount} items from chunk ${chunkIndex}, total items so far: ${allItems.length}`);
setImmediate(() => processChunk(offset + chunkSize, chunkIndex + 1));
});
};
processChunk(0);
});
}, cb);
}
}
//# sourceMappingURL=queue-messages-storage-list.js.map