@@ -5,7 +5,6 @@ import type { IoC } from '@intake24/api/ioc';
5
5
import type { Job } from '@intake24/api/jobs' ;
6
6
import type { JobData } from '@intake24/common/types' ;
7
7
import ioc from '@intake24/api/ioc' ;
8
- import { sleep } from '@intake24/api/util' ;
9
8
import { Task } from '@intake24/db' ;
10
9
11
10
import { QueueHandler } from './queue-handler' ;
@@ -63,172 +62,98 @@ export default class TasksQueueHandler extends QueueHandler<JobData> {
63
62
64
63
this . workers . push ( worker ) ;
65
64
66
- await this . clearRepeatableJobs ( ) ;
67
- await this . loadRepeatableJobs ( ) ;
65
+ await this . clearScheduledJobs ( ) ;
66
+ await this . loadScheduledJobs ( ) ;
68
67
69
68
this . logger . info ( `${ this . name } has been loaded.` ) ;
70
69
}
71
70
72
71
async processor ( job : BullJob < JobData > ) {
73
- const { id, name } = job ;
72
+ const { id, data : { type } } = job ;
74
73
75
74
if ( ! id ) {
76
75
this . logger . error ( `Queue ${ this . name } : Job ID missing.` ) ;
77
76
return ;
78
77
}
79
78
80
- const newJob = ioc . resolve < Job < any > > ( name ) ;
79
+ const newJob = ioc . resolve < Job < typeof type > > ( type ) ;
81
80
await newJob . run ( job ) ;
82
81
}
83
82
84
- async getRepeatableJobById ( id : string ) {
85
- const jobs = await this . queue . getRepeatableJobs ( ) ;
83
+ private async clearScheduledJobs ( ) {
84
+ const repeatableJobs = await this . queue . getJobSchedulers ( ) ;
86
85
87
- return jobs . find ( job => job . id ?. replace ( 'db-' , '' ) === id ) ;
86
+ await Promise . all ( repeatableJobs . map ( job => this . queue . removeJobScheduler ( job . key ) ) ) ;
88
87
}
89
88
90
- /**
91
- * Remove repeatable job(s) from queue
92
- *
93
- * @private
94
- * @param {string } [id]
95
- * @memberof TasksQueueHandler
96
- */
97
- private async clearRepeatableJobs ( id ?: string ) {
98
- const repeatableJobs = await this . queue . getRepeatableJobs ( ) ;
89
+ private createJobParams ( task : Task ) {
90
+ const { name, job, cron, params } = task ;
99
91
100
- for ( const job of repeatableJobs ) {
101
- if ( id && job . id ?. replace ( 'db-' , '' ) !== id )
102
- continue ;
103
-
104
- await this . queue . removeRepeatableByKey ( job . key ) ;
105
- }
92
+ return {
93
+ name,
94
+ data : { type : job , params } ,
95
+ opts : { pattern : cron } ,
96
+ } ;
106
97
}
107
98
108
- /**
109
- * Load repeatable jobs from DB to the queue
110
- *
111
- * @private
112
- * @memberof TasksQueueHandler
113
- */
114
- private async loadRepeatableJobs ( ) {
99
+ private async loadScheduledJobs ( ) {
115
100
const tasks = await Task . findAll ( { where : { active : true } } ) ;
116
101
117
- for ( const task of tasks )
118
- await this . addJob ( task ) ;
102
+ for ( const task of tasks ) {
103
+ const { name, data, opts } = this . createJobParams ( task ) ;
104
+ await this . queue . upsertJobScheduler ( `db-${ task . id } ` , opts , { name, data } ) ;
105
+ }
119
106
}
120
107
121
- /**
122
- * Push job into the queue
123
- *
124
- * @private
125
- * @param {Task } task
126
- * @memberof TasksQueueHandler
127
- */
128
- private async queueJob ( task : Task ) {
129
- const { id, job, cron, params } = task ;
108
+ private async getScheduledJobByKey ( key : string ) {
109
+ const jobs = await this . queue . getJobSchedulers ( ) ;
130
110
131
- return await this . queue . add ( job , { params } , { repeat : { pattern : cron } , jobId : `db- ${ id } ` } ) ;
111
+ return jobs . find ( job => job . key === key ) ;
132
112
}
133
113
134
- /**
135
- * Remove job from queue
136
- *
137
- * @private
138
- * @param {Task } task
139
- * @memberof TasksQueueHandler
140
- */
141
- private async dequeueJob ( task : Task ) {
142
- this . clearRepeatableJobs ( task . id ) ;
114
+ async getScheduledJobById ( id : string ) {
115
+ return await this . getScheduledJobByKey ( `db-${ id } ` ) ;
143
116
}
144
117
145
- /**
146
- * Add task's job to queue
147
- *
148
- * @param {Task } task
149
- * @memberof TasksQueueHandler
150
- */
151
- public async addJob ( task : Task ) {
152
- const { id, name, active } = task ;
153
-
154
- if ( ! active ) {
155
- this . logger . warn ( `Queue ${ this . name } : Task (ID: ${ id } , Name: ${ name } ) not set as active.` ) ;
156
- return ;
118
+ private async removeScheduledJobById ( id : string ) {
119
+ const job = await this . getScheduledJobById ( id ) ;
120
+ if ( ! job ) {
121
+ this . logger . debug ( `Queue ${ this . name } : Scheduled task (ID: ${ id } ) not in queue.` ) ;
122
+ return undefined ;
157
123
}
158
124
159
- await this . queueJob ( task ) ;
160
-
161
- this . logger . debug ( `Queue ${ this . name } : Task (ID: ${ id } , Name: ${ name } ) added.` ) ;
125
+ return await this . queue . removeJobScheduler ( job . key ) ;
162
126
}
163
127
164
- /**
165
- * Update task's job to queue
166
- *
167
- * @param {Task } task
168
- * @memberof TasksQueueHandler
169
- */
170
- public async updateJob ( task : Task ) {
171
- const { id, name, active } = task ;
128
+ public async updateTaskInQueue ( task : Task ) {
129
+ const { id, active } = task ;
172
130
173
- await this . dequeueJob ( task ) ;
174
-
175
- /*
176
- * Bullmq bug
177
- * When repeatable job removed right away and new job pushed in, job entry doesn't end up in redis store
178
- * Though queue.add returns correct job entry
179
- * Workaround: simple sleep/wait for few ms solves it for now
180
- */
181
- await sleep ( 20 ) ;
131
+ if ( ! active ) {
132
+ await this . removeScheduledJobById ( id ) ;
133
+ return ;
134
+ }
182
135
183
- if ( active )
184
- await this . queueJob ( task ) ;
136
+ const { name , data , opts } = this . createJobParams ( task ) ;
137
+ const job = await this . queue . upsertJobScheduler ( `db- ${ id } ` , opts , { name , data } ) ;
185
138
186
139
this . logger . debug ( `Queue ${ this . name } : Task (ID: ${ id } , Name: ${ name } ) updated.` ) ;
187
- }
188
-
189
- /**
190
- * Remove task's job from queue
191
- *
192
- * @param {Task } task
193
- * @memberof TasksQueueHandler
194
- */
195
- public async removeJob ( task : Task ) {
196
- const { id, name } = task ;
197
-
198
- await this . dequeueJob ( task ) ;
199
140
200
- this . logger . debug ( `Queue ${ this . name } : Task (ID: ${ id } , Name: ${ name } ) removed.` ) ;
141
+ return job ;
201
142
}
202
143
203
- /**
204
- * Add task's job to queue
205
- *
206
- * @param {Task } task
207
- * @memberof TasksQueueHandler
208
- */
209
- public async runJob ( task : Task ) {
210
- const { id, name, job, params } = task ;
144
+ public async removeTaskFromQueue ( task : Task ) {
145
+ const { id, name } = task ;
211
146
212
- await this . queue . add ( job , { params } , { delay : 500 } ) ;
147
+ await this . removeScheduledJobById ( id ) ;
213
148
214
- this . logger . debug ( `Queue ${ this . name } : Task (ID: ${ id } , Name: ${ name } ) queued .` ) ;
149
+ this . logger . debug ( `Queue ${ this . name } : Task (ID: ${ id } , Name: ${ name } ) updated .` ) ;
215
150
}
216
151
217
- /**
218
- * Pause all scheduled tasks in queue
219
- *
220
- * @memberof TasksQueueHandler
221
- */
222
152
public async pauseAll ( ) {
223
- await this . clearRepeatableJobs ( ) ;
153
+ await this . clearScheduledJobs ( ) ;
224
154
}
225
155
226
- /**
227
- * Resume all scheduled tasks in queue
228
- *
229
- * @memberof TasksQueueHandler
230
- */
231
156
public async resumeAll ( ) {
232
- await this . loadRepeatableJobs ( ) ;
157
+ await this . loadScheduledJobs ( ) ;
233
158
}
234
159
}
0 commit comments