chore(event-bus, workflow-engine): Enable more granualar queues configuration (#14201)
Summary
This PR adds BullMQ queue and worker configuration options to the workflow-engine-redis module, bringing feature parity with the event-bus-redis module. It also introduces per-queue
configuration options for fine-grained control over the three internal queues (main, job, and cleaner).
Key changes:
- Added per-queue BullMQ configuration options (mainQueueOptions, jobQueueOptions, cleanerQueueOptions and their worker counterparts) with shared defaults
- Unified Redis option naming across modules: deprecated url → redisUrl, options → redisOptions (with backward compatibility)
- Moved configuration resolution to the loader and registered options in the DI container
- Added comprehensive JSDoc documentation for all configuration options
- Added unit tests for option merging and queue/worker configuration
Configuration Example
```ts
// Simple configuration - same options for all queues
{
redisUrl: "redis://localhost:6379",
queueOptions: { defaultJobOptions: { removeOnComplete: 1000 } },
workerOptions: { concurrency: 10 }
}
```
```ts
// Advanced configuration - per-queue overrides
{
redisUrl: "redis://localhost:6379",
workerOptions: { concurrency: 10 }, // shared default
jobWorkerOptions: { concurrency: 5 }, // override for scheduled workflows
cleanerWorkerOptions: { concurrency: 1 } // override for cleanup (low priority)
}
```
This commit is contained in:
committed by
GitHub
parent
3e3e6c37bd
commit
144f0f4e2e
@@ -21,12 +21,17 @@ const redisMock = {
|
||||
unlink: () => jest.fn(),
|
||||
} as unknown as Redis
|
||||
|
||||
const simpleModuleOptions = { redisUrl: "test-url" }
|
||||
const moduleDeps = {
|
||||
logger: loggerMock,
|
||||
eventBusRedisConnection: redisMock,
|
||||
eventBusRedisQueueName: "events-queue",
|
||||
eventBusRedisQueueOptions: {},
|
||||
eventBusRedisWorkerOptions: {},
|
||||
eventBusRedisJobOptions: {},
|
||||
}
|
||||
|
||||
const moduleDeclaration = { scope: "internal" } as any
|
||||
|
||||
describe("RedisEventBusService", () => {
|
||||
let eventBus: RedisEventBusService
|
||||
let queue
|
||||
@@ -36,9 +41,7 @@ describe("RedisEventBusService", () => {
|
||||
beforeEach(async () => {
|
||||
jest.clearAllMocks()
|
||||
|
||||
eventBus = new RedisEventBusService(moduleDeps, simpleModuleOptions, {
|
||||
scope: "internal",
|
||||
})
|
||||
eventBus = new RedisEventBusService(moduleDeps, {}, moduleDeclaration)
|
||||
})
|
||||
|
||||
it("Creates a queue + worker", () => {
|
||||
@@ -62,9 +65,7 @@ describe("RedisEventBusService", () => {
|
||||
|
||||
it("Throws on isolated module declaration", () => {
|
||||
try {
|
||||
eventBus = new RedisEventBusService(moduleDeps, simpleModuleOptions, {
|
||||
scope: "internal",
|
||||
})
|
||||
eventBus = new RedisEventBusService(moduleDeps, {}, moduleDeclaration)
|
||||
} catch (error) {
|
||||
expect(error.message).toEqual(
|
||||
"At the moment this module can only be used with shared resources"
|
||||
@@ -78,9 +79,7 @@ describe("RedisEventBusService", () => {
|
||||
beforeEach(async () => {
|
||||
jest.clearAllMocks()
|
||||
|
||||
eventBus = new RedisEventBusService(moduleDeps, simpleModuleOptions, {
|
||||
scope: "internal",
|
||||
})
|
||||
eventBus = new RedisEventBusService(moduleDeps, {}, moduleDeclaration)
|
||||
|
||||
queue = (eventBus as any).queue_
|
||||
queue.addBulk = jest.fn()
|
||||
@@ -139,17 +138,15 @@ describe("RedisEventBusService", () => {
|
||||
|
||||
it("should add job to queue with module job options", async () => {
|
||||
eventBus = new RedisEventBusService(
|
||||
moduleDeps,
|
||||
{
|
||||
...simpleModuleOptions,
|
||||
jobOptions: {
|
||||
...moduleDeps,
|
||||
eventBusRedisJobOptions: {
|
||||
removeOnComplete: { age: 5 },
|
||||
attempts: 7,
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: "internal",
|
||||
}
|
||||
{},
|
||||
moduleDeclaration
|
||||
)
|
||||
|
||||
queue = (eventBus as any).queue_
|
||||
@@ -186,16 +183,14 @@ describe("RedisEventBusService", () => {
|
||||
|
||||
it("should add job to queue with default, local, and global options merged", async () => {
|
||||
eventBus = new RedisEventBusService(
|
||||
moduleDeps,
|
||||
{
|
||||
...simpleModuleOptions,
|
||||
jobOptions: {
|
||||
...moduleDeps,
|
||||
eventBusRedisJobOptions: {
|
||||
removeOnComplete: 5,
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: "internal",
|
||||
}
|
||||
{},
|
||||
moduleDeclaration
|
||||
)
|
||||
|
||||
queue = (eventBus as any).queue_
|
||||
@@ -340,9 +335,7 @@ describe("RedisEventBusService", () => {
|
||||
beforeEach(async () => {
|
||||
jest.clearAllMocks()
|
||||
|
||||
eventBus = new RedisEventBusService(moduleDeps, simpleModuleOptions, {
|
||||
scope: "internal",
|
||||
})
|
||||
eventBus = new RedisEventBusService(moduleDeps, {}, moduleDeclaration)
|
||||
|
||||
queue = (eventBus as any).queue_
|
||||
queue.addBulk = jest.fn()
|
||||
@@ -485,9 +478,7 @@ describe("RedisEventBusService", () => {
|
||||
beforeEach(async () => {
|
||||
jest.clearAllMocks()
|
||||
|
||||
eventBus = new RedisEventBusService(moduleDeps, simpleModuleOptions, {
|
||||
scope: "internal",
|
||||
})
|
||||
eventBus = new RedisEventBusService(moduleDeps, {}, moduleDeclaration)
|
||||
})
|
||||
|
||||
it("should process a simple event with no options", async () => {
|
||||
|
||||
Reference in New Issue
Block a user