@@ -14,6 +14,7 @@ export interface BullQueueConfig {
1414 port : number ;
1515 username ?: string ;
1616 password ?: string ;
17+ db ?: number ;
1718 } ;
1819 retryAttempts ?: number ;
1920}
@@ -25,17 +26,41 @@ export class BullQueue
2526 extends SequencerModule < BullQueueConfig >
2627 implements TaskQueue
2728{
29+ private activePromise ?: Promise < void > ;
30+
2831 public createWorker (
2932 name : string ,
3033 executor : ( data : TaskPayload ) => Promise < TaskPayload > ,
3134 options ?: { concurrency ?: number }
3235 ) : Closeable {
3336 const worker = new Worker < TaskPayload , TaskPayload > (
3437 name ,
35- async ( job ) => await executor ( job . data ) ,
38+ async ( job ) => {
39+ // This weird promise logic is needed to make sure the worker is not proving in parallel
40+ // This is by far not optimal - since it still picks up 1 task per queue but waits until
41+ // computing them, so that leads to bad performance over multiple workers.
42+ // For that we need to restructure tasks to be flowing through a single queue however
43+ while ( this . activePromise !== undefined ) {
44+ // eslint-disable-next-line no-await-in-loop
45+ await this . activePromise ;
46+ }
47+ let resOutside : ( ) => void = ( ) => { } ;
48+ const promise = new Promise < void > ( ( res ) => {
49+ resOutside = res ;
50+ } ) ;
51+ this . activePromise = promise ;
52+
53+ const result = await executor ( job . data ) ;
54+ this . activePromise = undefined ;
55+ void resOutside ( ) ;
56+
57+ return result ;
58+ } ,
3659 {
3760 concurrency : options ?. concurrency ?? 1 ,
3861 connection : this . config . redis ,
62+ stalledInterval : 60000 , // 1 minute
63+ lockDuration : 60000 , // 1 minute
3964
4065 metrics : { maxDataPoints : MetricsTime . ONE_HOUR * 24 } ,
4166 }
@@ -68,6 +93,7 @@ export class BullQueue
6893 name : queueName ,
6994
7095 async addTask ( payload : TaskPayload ) : Promise < { taskId : string } > {
96+ log . debug ( "Adding task: " , payload ) ;
7197 const job = await queue . add ( queueName , payload , {
7298 attempts : retryAttempts ?? 2 ,
7399 } ) ;
@@ -76,14 +102,25 @@ export class BullQueue
76102
77103 async onCompleted ( listener : ( payload : TaskPayload ) => Promise < void > ) {
78104 events . on ( "completed" , async ( result ) => {
79- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
80- await listener ( JSON . parse ( result . returnvalue ) as TaskPayload ) ;
105+ log . debug ( "Completed task: " , result ) ;
106+ try {
107+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
108+ await listener ( result . returnvalue as unknown as TaskPayload ) ;
109+ } catch ( e ) {
110+ // Catch error explicitly since this promise is dangling,
111+ // therefore any error will be voided as well
112+ log . error ( e ) ;
113+ }
114+ } ) ;
115+ events . on ( "error" , async ( error ) => {
116+ log . error ( "Error in worker" , error ) ;
81117 } ) ;
82118 await events . waitUntilReady ( ) ;
83119 } ,
84120
85121 async close ( ) : Promise < void > {
86122 await events . close ( ) ;
123+ await queue . drain ( ) ;
87124 await queue . close ( ) ;
88125 } ,
89126 } ;
0 commit comments