Skip to content

Commit

Permalink
docs: add Pub/Sub delivery model, refactor and clean up
Browse files Browse the repository at this point in the history
  • Loading branch information
weyoss committed Jan 25, 2024
1 parent 47affa1 commit 32db9dd
Show file tree
Hide file tree
Showing 48 changed files with 818 additions and 150 deletions.
31 changes: 17 additions & 14 deletions README.md
@@ -1,5 +1,5 @@
> [!IMPORTANT]
> Currently, RedisSMQ is going under heavy development. Pre-releases at any time may introduce new commits with breaking changes.
> Currently, RedisSMQ is going under heavy development. Pre-releases at any time may introduce new commits with breaking changes.
> The master branch always reflects the most recent changes. To view the latest release reference see [RedisSMQ v7.2.3](https://github.com/weyoss/redis-smq/tree/v7.2.3)
<div align="center" style="text-align: center">
Expand All @@ -17,22 +17,23 @@
<a href="https://npmjs.org/package/redis-smq" rel="nofollow"><img src="https://img.shields.io/npm/dm/redis-smq.svg" alt="NPM downloads" /></a>
</p>

RedisSMQ is a Node.js library for queuing messages (aka jobs) and processing them asynchronously with consumers. Backed by Redis, it allows scaling up your application with ease of use.
RedisSMQ is a Node.js library for queuing messages (aka jobs) and processing them asynchronously with consumers. Backed by Redis, it allows scaling up your typical applications with ease of use.

## Features

* [High-performance message processing](docs/performance.md).
* Flexible Producer/Consumer model which offers [Multi-Queue Producers](docs/producing-messages.md) & [Multi-Queue Consumers](docs/consuming-messages.md), focuses on simplicity and without tons of features. This makes RedisSMQ an ideal message broker for microservices-based applications.
* In case of failures, while delivering or processing a message, RedisSMQ can guaranty that the message is not lost and that it is redelivered [at-least-once](docs/api/classes/ProducibleMessage.md#setretrythreshold). When configured to do so, RedisSMQ can also ensure that the message is delivered [at-most-once](docs/api/classes/ProducibleMessage.md#setretrythreshold).
* Flexible Producer/Consumer model which offers [Multi-Queue Producers](docs/producing-messages.md) & [Multi-Queue Consumers](docs/consuming-messages.md).
* RedisSMQ offers different exchange types: [Direct Exchange](docs/message-exchanges.md#direct-exchange), [Topic Exchange](docs/message-exchanges.md#topic-exchange), and [FanOut Exchange](docs/message-exchanges.md#fanout-exchange) for publishing a message to one or multiple queues.
* 3 queuing strategies that you may use depending on your needs and requirements: [FIFO queues, LIFO queues, and Reliable Priority Queues](docs/queues.md).
* A message can be [set to expire](docs/api/classes/ProducibleMessage.md#setttl) if it has not been delivered within a given amount of time. [Consumption timeout](docs/api/classes/ProducibleMessage.md#setconsumetimeout) allows canceling a message consumption if a consumer did not acknowledge the message for a period of time.
* [Queue Rate Limiting](docs/queue-rate-limiting.md) which allows to control the rate at which the messages are consumed from a given queue.
* Builtin [message scheduler](docs/scheduling-messages.md) allowing to delay a message, to deliver a message for N times with an optional period between deliveries, or simply to schedule message delivery using CRON expressions.
* [Multiplexing](/docs/multiplexing.md): A feature which allows message handlers to use a single redis connection to dequeue and consume messages.
* An [HTTP interface](https://github.com/weyoss/redis-smq-monitor) is provided to interact with the MQ. RedisSMQ can be managed also from your [web browser](https://github.com/weyoss/redis-smq-monitor-client).
* Depending on [your preferences](docs/configuration.md), RedisSMQ can use either [node-redis v3](https://github.com/redis/node-redis/tree/v3.1.2), [node-redis v4](https://github.com/redis/node-redis), or [ioredis](https://github.com/luin/ioredis).
* RedisSMQ is [highly optimized](https://lgtm.com/projects/g/weyoss/redis-smq/context:javascript), implemented using pure callbacks, with small memory footprint and no memory leaks. See [Callback vs Promise vs Async/Await benchmarks](https://gist.github.com/weyoss/24f9ecbda175d943a48cb7ec38bde821).
* Supports [Point-2-Point](docs/queue-delivery-models.md#point-2-point-delivery-model) and [Pub/Sub](docs/queue-delivery-models.md#pubsub-delivery-model) [delivery models](docs/queue-delivery-models.md).
* Both [delivery models](docs/queue-delivery-models.md) are reliable. For cases of failure, while delivering/consuming messages, [at-least-once](docs/api/classes/ProducibleMessage.md#setretrythreshold) and [at-most-once](docs/api/classes/ProducibleMessage.md#setretrythreshold) modes may be configured.
* [3 queuing strategies](docs/queues.md): [FIFO queues](docs/queues.md#fifo-first-in-first-out-queues), [LIFO queues](docs/queues.md#lifo-last-in-first-out-queues), and [Reliable Priority Queues](docs/queues.md#priority-queues).
* Messages can be [set to expire](docs/api/classes/ProducibleMessage.md#setttl) when not delivered within a given amount of time or to have a [consumption timeout](docs/api/classes/ProducibleMessage.md#setconsumetimeout) while being in process.
* Queues may be [rate Limited](docs/queue-rate-limiting.md) to control the rate at which the messages are consumed.
* Has a builtin [scheduler](docs/scheduling-messages.md) allowing messages [to be delayed](docs/api/classes/ProducibleMessage.md#setscheduleddelay), [to be delivered for N times](docs/api/classes/ProducibleMessage.md#setscheduledrepeat) with an optional [period between deliveries](docs/api/classes/ProducibleMessage.md#setscheduledrepeatperiod), or simply [to be scheduled using CRON expressions](docs/api/classes/ProducibleMessage.md#setscheduledcron).
* Provides [an HTTP API](https://github.com/weyoss/redis-smq-monitor) to interact with the message queue for external services.
* RedisSMQ can be managed also from your [web browser](https://github.com/weyoss/redis-smq-monitor-client).
* Either [node-redis](https://github.com/redis/node-redis) or [ioredis](https://github.com/luin/ioredis) can be used as a Redis client.
* [Highly optimized](https://lgtm.com/projects/g/weyoss/redis-smq/context:javascript), implemented using pure callbacks, with small memory footprint and no memory leaks. See [Callback vs Promise vs Async/Await benchmarks](https://gist.github.com/weyoss/24f9ecbda175d943a48cb7ec38bde821).
* [Both ESM & CJS modules are supported](docs/esm-cjs-modules.md).

## RedisSMQ Use Case: Multi-Queue Producers & Multi-Queue Consumers
Expand Down Expand Up @@ -65,14 +66,16 @@ A queue is responsible for holding messages which are produced by producers and
### Creating a queue

```javascript
const { Queue, EQueueType } = require('redis-smq');
const { Queue, EQueueType, EQueueDeliveryModel } = require('redis-smq');

const queue = new Queue();

// Creating a LIFO queue
queue.save('my_queue', EQueueType.LIFO_QUEUE, (err) => console.log(err));
queue.save('my_queue', EQueueType.LIFO_QUEUE, EQueueDeliveryModel.POINT_TO_POINT, (err) => console.log(err));
```

In the example above we are defining a [LIFO queue](docs/queues.md#lifo-last-in-first-out-queues) with a [POINT-2-POINT delivery model](docs/queue-delivery-models.md#point-2-point-delivery-model).

### Producing a message

```javascript
Expand Down
2 changes: 2 additions & 0 deletions docs/README.md
Expand Up @@ -10,11 +10,13 @@ See [API Reference](api/README.md) for more details.

- [Configuration](configuration.md)
- [Queues](queues.md)
- [Queue Delivery Models](queue-delivery-models.md)
- [Producing Messages](producing-messages.md)
- [Consuming Messages](consuming-messages.md)
- [Messages](messages.md)
- [Message Exchanges](message-exchanges.md)
- [Queue Rate Limiting](queue-rate-limiting.md)
- [Exchanges and Delivery Models](exchanges-and-delivery-models.md)
- [Multiplexing](multiplexing.md)
- [Scheduling Messages](scheduling-messages.md)
- [Performance](performance.md)
Expand Down
112 changes: 60 additions & 52 deletions docs/api/README.md
Expand Up @@ -12,15 +12,15 @@
- [EMessagePriority](enums/EMessagePriority.md)
- [EMessageProperty](enums/EMessageProperty.md)
- [EMessagePropertyStatus](enums/EMessagePropertyStatus.md)
- [EQueueDeliveryModel](enums/EQueueDeliveryModel.md)
- [EQueueProperty](enums/EQueueProperty.md)
- [EQueueType](enums/EQueueType.md)

### Classes

- [Configuration](classes/Configuration.md)
- [Consumer](classes/Consumer.md)
- [ExchangeDirect](classes/ExchangeDirect.md)
- [ExchangeFanOut](classes/ExchangeFanOut.md)
- [ConsumerGroups](classes/ConsumerGroups.md)
- [ExchangeTopic](classes/ExchangeTopic.md)
- [Message](classes/Message.md)
- [Namespace](classes/Namespace.md)
Expand All @@ -34,13 +34,20 @@
- [QueueRateLimit](classes/QueueRateLimit.md)
- [QueueScheduledMessages](classes/QueueScheduledMessages.md)

### Errors
## Errors

- [ConsumerError](classes/ConsumerError.md)
- [ConsumerGroupDeleteError](classes/ConsumerGroupDeleteError.md)
- [ConsumerGroupIdNotFoundError](classes/ConsumerGroupIdNotFoundError.md)
- [ConsumerGroupIdNotSupportedError](classes/ConsumerGroupIdNotSupportedError.md)
- [ConsumerGroupIdRequiredError](classes/ConsumerGroupIdRequiredError.md)
- [ConsumerInvalidGroupIdError](classes/ConsumerInvalidGroupIdError.md)
- [ConsumerMessageHandlerAlreadyExistsError](classes/ConsumerMessageHandlerAlreadyExistsError.md)
- [ExchangeDirect](classes/ExchangeDirect.md)
- [ExchangeError](classes/ExchangeError.md)
- [ExchangeFanOut](classes/ExchangeFanOut.md)
- [ExchangeFanOutError](classes/ExchangeFanOutError.md)
- [ExchangeInvalidDataError](classes/ExchangeInvalidDataError.md)
- [ExchangeError](classes/ExchangeError.md)
- [MessageDeleteError](classes/MessageDeleteError.md)
- [MessageDestinationQueueAlreadySetError](classes/MessageDestinationQueueAlreadySetError.md)
- [MessageDestinationQueueRequiredError](classes/MessageDestinationQueueRequiredError.md)
Expand All @@ -49,16 +56,18 @@
- [MessageNotFoundError](classes/MessageNotFoundError.md)
- [ProducerError](classes/ProducerError.md)
- [ProducerInstanceNotRunningError](classes/ProducerInstanceNotRunningError.md)
- [ProducerMessageExchangeRequiredError](classes/ProducerMessageExchangeRequiredError.md)
- [ProducerMessageNotPublishedError](classes/ProducerMessageNotPublishedError.md)
- [ProducerMessageNotScheduledError](classes/ProducerMessageNotScheduledError.md)
- [QueueRateLimitError](classes/QueueRateLimitError.md)
- [QueueNamespaceNotFoundError](classes/QueueNamespaceNotFoundError.md)
- [QueueNotEmptyError](classes/QueueNotEmptyError.md)
- [QueueNotFoundError](classes/QueueNotFoundError.md)
- [ProducerQueueWithoutConsumerGroupsError](classes/ProducerQueueWithoutConsumerGroupsError.md)
- [QueueError](classes/QueueError.md)
- [QueueExistsError](classes/QueueExistsError.md)
- [QueueHasRunningConsumersError](classes/QueueHasRunningConsumersError.md)
- [QueueMessageRequeueError](classes/QueueMessageRequeueError.md)
- [QueueNamespaceNotFoundError](classes/QueueNamespaceNotFoundError.md)
- [QueueNotEmptyError](classes/QueueNotEmptyError.md)
- [QueueNotFoundError](classes/QueueNotFoundError.md)
- [QueueRateLimitError](classes/QueueRateLimitError.md)

### Interfaces

Expand All @@ -76,10 +85,14 @@
- [IMessagesConfigStorageOptions](interfaces/IMessagesConfigStorageOptions.md)
- [IMessagesConfigStorageOptionsRequired](interfaces/IMessagesConfigStorageOptionsRequired.md)
- [IMessagesConfigStorageRequired](interfaces/IMessagesConfigStorageRequired.md)
- [IQueueConsumerGroupParams](interfaces/IQueueConsumerGroupParams.md)
- [IQueueGroupConsumersPendingCount](interfaces/IQueueGroupConsumersPendingCount.md)
- [IQueueMessages](interfaces/IQueueMessages.md)
- [IQueueMessagesCount](interfaces/IQueueMessagesCount.md)
- [IQueueMessagesPage](interfaces/IQueueMessagesPage.md)
- [IQueueMessagesRequeuable](interfaces/IQueueMessagesRequeuable.md)
- [IQueueParams](interfaces/IQueueParams.md)
- [IQueueParsedParams](interfaces/IQueueParsedParams.md)
- [IQueueProperties](interfaces/IQueueProperties.md)
- [IQueueRateLimit](interfaces/IQueueRateLimit.md)
- [IRedisSMQConfig](interfaces/IRedisSMQConfig.md)
Expand All @@ -92,18 +105,15 @@
- [TConsumerRedisKeys](README.md#tconsumerrediskeys)
- [TEventListenersConfig](README.md#teventlistenersconfig)
- [TExchange](README.md#texchange)
- [TExchangeDirect](README.md#texchangedirect)
- [TExchangeDirectBindingParams](README.md#texchangedirectbindingparams)
- [TExchangeDirectSerialized](README.md#texchangedirectserialized)
- [TExchangeFanOut](README.md#texchangefanout)
- [TExchangeFanOutBindingParams](README.md#texchangefanoutbindingparams)
- [TExchangeFanOutSerialized](README.md#texchangefanoutserialized)
- [TExchangeSerialized](README.md#texchangeserialized)
- [TExchangeTopic](README.md#texchangetopic)
- [TExchangeTopicBindingParams](README.md#texchangetopicbindingparams)
- [TExchangeTopicSerialized](README.md#texchangetopicserialized)
- [TMessageConsumeOptions](README.md#tmessageconsumeoptions)
- [TQueueConsumer](README.md#tqueueconsumer)
- [TQueueExtendedParams](README.md#tqueueextendedparams)
- [TQueueMessagesPaginationParams](README.md#tqueuemessagespaginationparams)
- [TQueueMessagesParams](README.md#tqueuemessagesparams)
- [TRedisSMQEvent](README.md#tredissmqevent)
- [TTopicParams](README.md#ttopicparams)

Expand Down Expand Up @@ -163,13 +173,7 @@ ___

### TExchange

Ƭ **TExchange**: [`TExchangeDirect`](README.md#texchangedirect) \| [`TExchangeTopic`](README.md#texchangetopic) \| [`TExchangeFanOut`](README.md#texchangefanout)

___

### TExchangeDirect

Ƭ **TExchangeDirect**: [`IExchange`](interfaces/IExchange.md)\<[`TExchangeDirectBindingParams`](README.md#texchangedirectbindingparams), [`DIRECT`](enums/EExchangeType.md#direct)\>
Ƭ **TExchange**: [`ExchangeDirect`](classes/ExchangeDirect.md) \| [`ExchangeTopic`](classes/ExchangeTopic.md) \| [`ExchangeFanOut`](classes/ExchangeFanOut.md)

___

Expand All @@ -179,39 +183,15 @@ ___

___

### TExchangeDirectSerialized

Ƭ **TExchangeDirectSerialized**: [`IExchangeSerialized`](interfaces/IExchangeSerialized.md)\<[`TExchangeDirectBindingParams`](README.md#texchangedirectbindingparams), [`DIRECT`](enums/EExchangeType.md#direct)\>

___

### TExchangeFanOut

Ƭ **TExchangeFanOut**: [`IExchange`](interfaces/IExchange.md)\<[`TExchangeFanOutBindingParams`](README.md#texchangefanoutbindingparams), [`FANOUT`](enums/EExchangeType.md#fanout)\>

___

### TExchangeFanOutBindingParams

Ƭ **TExchangeFanOutBindingParams**: `string`

___

### TExchangeFanOutSerialized

Ƭ **TExchangeFanOutSerialized**: [`IExchangeSerialized`](interfaces/IExchangeSerialized.md)\<[`TExchangeFanOutBindingParams`](README.md#texchangefanoutbindingparams), [`FANOUT`](enums/EExchangeType.md#fanout)\>

___

### TExchangeSerialized

Ƭ **TExchangeSerialized**: [`TExchangeDirectSerialized`](README.md#texchangedirectserialized) \| [`TExchangeTopicSerialized`](README.md#texchangetopicserialized) \| [`TExchangeFanOutSerialized`](README.md#texchangefanoutserialized)

___

### TExchangeTopic

Ƭ **TExchangeTopic**: [`IExchange`](interfaces/IExchange.md)\<[`TExchangeTopicBindingParams`](README.md#texchangetopicbindingparams), [`TOPIC`](enums/EExchangeType.md#topic)\>
Ƭ **TExchangeSerialized**: `ReturnType`\<[`ExchangeDirect`](classes/ExchangeDirect.md)[``"toJSON"``]\> \| `ReturnType`\<[`ExchangeTopic`](classes/ExchangeTopic.md)[``"toJSON"``]\> \| `ReturnType`\<[`ExchangeFanOut`](classes/ExchangeFanOut.md)[``"toJSON"``]\>

___

Expand All @@ -221,12 +201,6 @@ ___

___

### TExchangeTopicSerialized

Ƭ **TExchangeTopicSerialized**: [`IExchangeSerialized`](interfaces/IExchangeSerialized.md)\<[`TExchangeTopicBindingParams`](README.md#texchangetopicbindingparams), [`TOPIC`](enums/EExchangeType.md#topic)\>

___

### TMessageConsumeOptions

Ƭ **TMessageConsumeOptions**: `Object`
Expand Down Expand Up @@ -257,6 +231,40 @@ ___

___

### TQueueExtendedParams

Ƭ **TQueueExtendedParams**: `string` \| [`IQueueParams`](interfaces/IQueueParams.md) \| [`IQueueConsumerGroupParams`](interfaces/IQueueConsumerGroupParams.md)

___

### TQueueMessagesPaginationParams

Ƭ **TQueueMessagesPaginationParams**: `Object`

#### Type declaration

| Name | Type |
| :------ | :------ |
| `consumerGroupId?` | `string` \| ``null`` |
| `page` | `number` |
| `pageSize` | `number` |
| `queue` | `string` \| [`IQueueParams`](interfaces/IQueueParams.md) |

___

### TQueueMessagesParams

Ƭ **TQueueMessagesParams**: `Object`

#### Type declaration

| Name | Type |
| :------ | :------ |
| `consumerGroupId?` | `string` \| ``null`` |
| `queue` | `string` \| [`IQueueParams`](interfaces/IQueueParams.md) |

___

### TRedisSMQEvent

- [`TEvent`](https://github.com/weyoss/redis-smq-common/blob/master/docs/api/README.md#tevent)
Expand Down
8 changes: 4 additions & 4 deletions docs/api/classes/Consumer.md
Expand Up @@ -59,7 +59,7 @@ Base.constructor

| Name | Type |
| :------ | :------ |
| `queue` | `string` \| [`IQueueParams`](../interfaces/IQueueParams.md) |
| `queue` | [`TQueueExtendedParams`](../README.md#tqueueextendedparams) |
| `cb` | `ICallback`\<`void`\> |

#### Returns
Expand All @@ -76,7 +76,7 @@ ___

| Name | Type |
| :------ | :------ |
| `queue` | `string` \| [`IQueueParams`](../interfaces/IQueueParams.md) |
| `queue` | [`TQueueExtendedParams`](../README.md#tqueueextendedparams) |
| `messageHandler` | [`TConsumerMessageHandler`](../README.md#tconsumermessagehandler) |
| `cb` | `ICallback`\<`void`\> |

Expand All @@ -102,11 +102,11 @@ ___

### getQueues

**getQueues**(): [`IQueueParams`](../interfaces/IQueueParams.md)[]
**getQueues**(): [`IQueueParsedParams`](../interfaces/IQueueParsedParams.md)[]

#### Returns

[`IQueueParams`](../interfaces/IQueueParams.md)[]
[`IQueueParsedParams`](../interfaces/IQueueParsedParams.md)[]

___

Expand Down
10 changes: 10 additions & 0 deletions docs/api/classes/ConsumerError.md
Expand Up @@ -10,6 +10,16 @@

↳↳ [`ConsumerMessageHandlerAlreadyExistsError`](ConsumerMessageHandlerAlreadyExistsError.md)

↳↳ [`ConsumerGroupDeleteError`](ConsumerGroupDeleteError.md)

↳↳ [`ConsumerGroupIdNotFoundError`](ConsumerGroupIdNotFoundError.md)

↳↳ [`ConsumerGroupIdNotSupportedError`](ConsumerGroupIdNotSupportedError.md)

↳↳ [`ConsumerGroupIdRequiredError`](ConsumerGroupIdRequiredError.md)

↳↳ [`ConsumerInvalidGroupIdError`](ConsumerInvalidGroupIdError.md)

## Table of contents

### Constructors
Expand Down
35 changes: 35 additions & 0 deletions docs/api/classes/ConsumerGroupDeleteError.md
@@ -0,0 +1,35 @@
[RedisSMQ](../../../README.md) / [Docs](../../README.md) / [API Reference](../README.md) / ConsumerGroupDeleteError

# Class: ConsumerGroupDeleteError

## Hierarchy

- [`ConsumerError`](ConsumerError.md)

**`ConsumerGroupDeleteError`**

## Table of contents

### Constructors

- [constructor](ConsumerGroupDeleteError.md#constructor)

## Constructors

### constructor

**new ConsumerGroupDeleteError**(`message?`): [`ConsumerGroupDeleteError`](ConsumerGroupDeleteError.md)

#### Parameters

| Name | Type |
| :------ | :------ |
| `message?` | `string` |

#### Returns

[`ConsumerGroupDeleteError`](ConsumerGroupDeleteError.md)

#### Inherited from

[ConsumerError](ConsumerError.md).[constructor](ConsumerError.md#constructor)

0 comments on commit 32db9dd

Please sign in to comment.