@abtnode/queue 1.16.8-beta-186fd5aa → 1.16.8-next-d1e52353
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.js +101 -144
- package/lib/logger.js +8 -7
- package/lib/store/nedb.js +74 -0
- package/lib/store/sequelize.js +65 -0
- package/package.json +6 -6
- package/lib/store.js +0 -104
package/lib/index.js
CHANGED
|
@@ -4,28 +4,31 @@ const Queue = require('fastq');
|
|
|
4
4
|
const EventEmitter = require('events');
|
|
5
5
|
const tryWithTimeout = require('@abtnode/util/lib/try-with-timeout');
|
|
6
6
|
const sleep = require('@abtnode/util/lib/sleep');
|
|
7
|
-
const debug = require('debug')('core/queue');
|
|
8
7
|
|
|
9
|
-
const
|
|
8
|
+
const NedbStore = require('./store/nedb');
|
|
10
9
|
const logger = require('./logger');
|
|
11
10
|
|
|
12
11
|
const CANCELLED = '__CANCELLED__';
|
|
13
|
-
const MIN_DELAY = 5;
|
|
12
|
+
const MIN_DELAY = process.env.NODE_ENV === 'test' ? 2 : 5;
|
|
14
13
|
|
|
15
14
|
/**
|
|
16
15
|
*
|
|
17
|
-
* @param {Object}
|
|
18
|
-
* @param {string}
|
|
19
|
-
* @param {
|
|
20
|
-
* @param {
|
|
21
|
-
* @param {
|
|
22
|
-
* @param {
|
|
23
|
-
* @param {number}
|
|
24
|
-
* @param {number}
|
|
25
|
-
* @param {number}
|
|
26
|
-
* @param {
|
|
16
|
+
* @param {Object} config
|
|
17
|
+
* @param {string} [config.file] filepath of JobStore
|
|
18
|
+
* @param {object} [config.store] queue store instance
|
|
19
|
+
* @param {function} config.onJob called on receives job
|
|
20
|
+
* @param {Object} [config.options] options
|
|
21
|
+
* @param {string} [config.options.id] id of the job
|
|
22
|
+
* @param {number} [config.options.concurrency] [param=1] number of concurrent jobs
|
|
23
|
+
* @param {number} [config.options.maxRetries] [param=1] number of max retries, default 1
|
|
24
|
+
* @param {number} [config.options.maxTimeout] [param=86400000] max timeout, in ms, default 86400000ms(1d)
|
|
25
|
+
* @param {number} [config.options.retryDelay] [param=0] retry delay, in ms, default 0ms
|
|
26
|
+
* @param {boolean} [config.options.enableScheduledJob] [param=false] enable scheduled job or not, default is false
|
|
27
27
|
*/
|
|
28
|
-
module.exports = function createQueue({ file, onJob, options = {} }) {
|
|
28
|
+
module.exports = function createQueue({ file, store, onJob, options = {} }) {
|
|
29
|
+
if (!file && !store) {
|
|
30
|
+
throw new Error('Either nedb file path or store instance must be provided to create a queue');
|
|
31
|
+
}
|
|
29
32
|
if (typeof onJob !== 'function') {
|
|
30
33
|
throw new Error('onJob must be a function to create a queue');
|
|
31
34
|
}
|
|
@@ -42,13 +45,16 @@ module.exports = function createQueue({ file, onJob, options = {} }) {
|
|
|
42
45
|
const maxTimeout = Math.max(options.maxTimeout || defaults.maxTimeout, 0);
|
|
43
46
|
const retryDelay = Math.max(options.retryDelay || defaults.retryDelay, 0);
|
|
44
47
|
const enableScheduledJob = typeof options.enableScheduledJob === 'boolean' ? options.enableScheduledJob : false;
|
|
48
|
+
const queueEvents = new EventEmitter();
|
|
45
49
|
|
|
46
50
|
if (typeof options.maxRetries === 'number' && options.maxRetries >= 0) {
|
|
47
51
|
maxRetries = options.maxRetries;
|
|
48
52
|
}
|
|
49
53
|
|
|
50
|
-
|
|
51
|
-
|
|
54
|
+
if (file) {
|
|
55
|
+
// eslint-disable-next-line no-param-reassign
|
|
56
|
+
store = new NedbStore(file);
|
|
57
|
+
}
|
|
52
58
|
|
|
53
59
|
const getJobId = (jobId, job) =>
|
|
54
60
|
jobId || (typeof options.id === 'function' ? options.id(job) : uuid.v4()) || uuid.v4();
|
|
@@ -77,11 +83,11 @@ module.exports = function createQueue({ file, onJob, options = {} }) {
|
|
|
77
83
|
|
|
78
84
|
/**
|
|
79
85
|
* Push job to the queue, the old way of calling `push(job, jobId, persist)` will be deprecated
|
|
80
|
-
* @param {object}
|
|
81
|
-
* @param {object}
|
|
82
|
-
* @param {string}
|
|
83
|
-
* @param {boolean}
|
|
84
|
-
* @param {number}
|
|
86
|
+
* @param {object} params
|
|
87
|
+
* @param {object} params.job The data of the job
|
|
88
|
+
* @param {string} params.jobId Optional, custom jobId
|
|
89
|
+
* @param {boolean} params.persist [persist=true] Persisting the job to the database
|
|
90
|
+
* @param {number} params.delay Optional, default with no delay, unit is second, for example: 10 will run after 10s
|
|
85
91
|
* @returns
|
|
86
92
|
*/
|
|
87
93
|
const push = (...args) => {
|
|
@@ -101,10 +107,10 @@ module.exports = function createQueue({ file, onJob, options = {} }) {
|
|
|
101
107
|
[job, jobId, persist = true] = args;
|
|
102
108
|
}
|
|
103
109
|
|
|
104
|
-
const
|
|
110
|
+
const events = new EventEmitter();
|
|
105
111
|
const emit = (e, data) => {
|
|
106
112
|
queueEvents.emit(e, data);
|
|
107
|
-
|
|
113
|
+
events.emit(e, data);
|
|
108
114
|
};
|
|
109
115
|
|
|
110
116
|
if (!job) {
|
|
@@ -123,41 +129,18 @@ module.exports = function createQueue({ file, onJob, options = {} }) {
|
|
|
123
129
|
throw new Error(`minimum delay is ${MIN_DELAY}s`);
|
|
124
130
|
}
|
|
125
131
|
|
|
126
|
-
store.addJob(
|
|
127
|
-
id,
|
|
128
|
-
|
|
129
|
-
(err) => {
|
|
130
|
-
if (err) {
|
|
131
|
-
logger.error('failed to add job', err);
|
|
132
|
-
emit('failed', { id, job, error: err });
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
emit('queued', { id, job });
|
|
137
|
-
},
|
|
138
|
-
{ delay, willRunAt: Date.now() + delay * 1000 }
|
|
139
|
-
);
|
|
140
|
-
|
|
141
|
-
jobEvents.id = id;
|
|
132
|
+
store.addJob(id, job, { delay, willRunAt: Date.now() + delay * 1000 }).then(() => {
|
|
133
|
+
emit('queued', { id, job });
|
|
134
|
+
});
|
|
142
135
|
|
|
143
|
-
|
|
136
|
+
events.id = id;
|
|
137
|
+
return events;
|
|
144
138
|
}
|
|
145
139
|
|
|
146
140
|
// eslint-disable-next-line no-shadow
|
|
147
|
-
const clearJob = (id
|
|
148
|
-
store.deleteJob(id, (e) => {
|
|
149
|
-
if (typeof cb === 'function') {
|
|
150
|
-
cb(e);
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
if (e) {
|
|
155
|
-
logger.error('Failed to delete job from persistent store', { error: e, id });
|
|
156
|
-
}
|
|
157
|
-
});
|
|
158
|
-
};
|
|
141
|
+
const clearJob = (id) => store.deleteJob(id);
|
|
159
142
|
|
|
160
|
-
const onJobComplete = (err, result) => {
|
|
143
|
+
const onJobComplete = async (err, result) => {
|
|
161
144
|
if (result === CANCELLED) {
|
|
162
145
|
emit('cancelled', { id, job, result });
|
|
163
146
|
clearJob(id);
|
|
@@ -170,125 +153,99 @@ module.exports = function createQueue({ file, onJob, options = {} }) {
|
|
|
170
153
|
return;
|
|
171
154
|
}
|
|
172
155
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
emit('failed', { id, job, error: err });
|
|
177
|
-
return;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
if (attrs.retryCount >= maxRetries) {
|
|
156
|
+
try {
|
|
157
|
+
const doc = await store.getJob(id);
|
|
158
|
+
if (doc.retryCount >= maxRetries) {
|
|
181
159
|
logger.info('fail job', { id });
|
|
182
|
-
clearJob(id
|
|
183
|
-
|
|
184
|
-
});
|
|
160
|
+
await clearJob(id);
|
|
161
|
+
emit('failed', { id, job, error: err });
|
|
185
162
|
return;
|
|
186
163
|
}
|
|
187
164
|
|
|
188
|
-
store.updateJob(id, { retryCount:
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
}, retryDelay);
|
|
200
|
-
});
|
|
201
|
-
});
|
|
165
|
+
await store.updateJob(id, { retryCount: doc.retryCount + 1 });
|
|
166
|
+
logger.info('retry job', { id, count: doc.retryCount + 1 });
|
|
167
|
+
setTimeout(() => {
|
|
168
|
+
queue.unshift({ id, job }, onJobComplete);
|
|
169
|
+
}, retryDelay);
|
|
170
|
+
// eslint-disable-next-line no-shadow
|
|
171
|
+
} catch (err) {
|
|
172
|
+
console.error(err);
|
|
173
|
+
await clearJob(id);
|
|
174
|
+
emit('failed', { id, job, error: err });
|
|
175
|
+
}
|
|
202
176
|
};
|
|
203
177
|
|
|
204
|
-
|
|
205
|
-
store.addJob(id, job, (err) => {
|
|
206
|
-
if (err) {
|
|
207
|
-
logger.error('failed to add job', err);
|
|
208
|
-
emit('failed', { id, job, error: err });
|
|
209
|
-
return;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
setImmediate(() => {
|
|
213
|
-
emit('queued', { id, job });
|
|
214
|
-
logger.info('queue job', { id, job, persist });
|
|
215
|
-
queue.push({ id, job, persist }, onJobComplete);
|
|
216
|
-
});
|
|
217
|
-
});
|
|
218
|
-
} else {
|
|
178
|
+
const queueJob = () =>
|
|
219
179
|
setImmediate(() => {
|
|
220
180
|
emit('queued', { id, job, persist });
|
|
221
181
|
logger.info('queue job', { id, job });
|
|
222
182
|
queue.push({ id, job, persist }, onJobComplete);
|
|
223
183
|
});
|
|
224
|
-
}
|
|
225
184
|
|
|
226
|
-
|
|
185
|
+
if (persist) {
|
|
186
|
+
store.addJob(id, job).then(queueJob);
|
|
187
|
+
} else {
|
|
188
|
+
queueJob();
|
|
189
|
+
}
|
|
227
190
|
|
|
228
|
-
|
|
191
|
+
events.id = id;
|
|
192
|
+
return events;
|
|
229
193
|
};
|
|
230
194
|
|
|
231
|
-
const cancel = async (id) =>
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
return reject(e);
|
|
236
|
-
}
|
|
237
|
-
return resolve(doc ? doc.job : null);
|
|
238
|
-
});
|
|
239
|
-
});
|
|
240
|
-
|
|
241
|
-
const getJob = async (id) =>
|
|
242
|
-
new Promise((resolve, reject) => {
|
|
243
|
-
store.getJob(id, (e, doc) => {
|
|
244
|
-
if (e) {
|
|
245
|
-
return reject(e);
|
|
246
|
-
}
|
|
195
|
+
const cancel = async (id) => {
|
|
196
|
+
const doc = await store.updateJob(id, { cancelled: true });
|
|
197
|
+
return doc ? doc.job : null;
|
|
198
|
+
};
|
|
247
199
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
200
|
+
const getJob = async (id) => {
|
|
201
|
+
const doc = await store.getJob(id);
|
|
202
|
+
return doc ? doc.job : null;
|
|
203
|
+
};
|
|
251
204
|
|
|
252
205
|
// Populate the queue on startup
|
|
253
|
-
store.
|
|
206
|
+
store.loadDatabase(async (err) => {
|
|
254
207
|
if (err) {
|
|
255
|
-
logger.error('Can not load job database
|
|
208
|
+
logger.error('Can not load job database', { error: err });
|
|
256
209
|
throw err;
|
|
257
210
|
}
|
|
258
211
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
});
|
|
212
|
+
try {
|
|
213
|
+
const jobs = await store.getJobs();
|
|
214
|
+
logger.info('queue jobs to populate', { count: jobs.length });
|
|
215
|
+
jobs.forEach((x) => {
|
|
216
|
+
if (x.job && x.id) {
|
|
217
|
+
push(x.job, x.id, false);
|
|
218
|
+
} else {
|
|
219
|
+
logger.info('skip invalid job from db', { job: x });
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
// eslint-disable-next-line no-shadow
|
|
223
|
+
} catch (err) {
|
|
224
|
+
console.error(err);
|
|
225
|
+
logger.error('Can not load existing jobs', { error: err });
|
|
226
|
+
}
|
|
275
227
|
});
|
|
276
228
|
|
|
277
229
|
const loop = async () => {
|
|
278
230
|
if (enableScheduledJob === true) {
|
|
279
231
|
// eslint-disable-next-line no-constant-condition
|
|
280
232
|
while (true) {
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
233
|
+
try {
|
|
234
|
+
/* eslint-disable no-await-in-loop */
|
|
235
|
+
const jobs = await store.getScheduledJobs();
|
|
236
|
+
jobs.forEach((x) => {
|
|
237
|
+
if (x.job && x.id) {
|
|
238
|
+
push(x.job, x.id, false);
|
|
239
|
+
} else {
|
|
240
|
+
logger.info('skip invalid job from db', { job: x });
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
} catch (err) {
|
|
244
|
+
console.error(err);
|
|
245
|
+
logger.error('Can not load scheduled jobs', { error: err });
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
await sleep(MIN_DELAY / 2);
|
|
292
249
|
}
|
|
293
250
|
}
|
|
294
251
|
};
|
package/lib/logger.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
const debug = require('debug')(require('../package.json').name);
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
module.exports = {
|
|
4
|
+
error: debug,
|
|
5
|
+
warn: debug,
|
|
6
|
+
info: debug,
|
|
7
|
+
debug,
|
|
8
|
+
verbose: debug,
|
|
9
|
+
silly: debug,
|
|
10
|
+
};
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/* eslint-disable no-underscore-dangle */
|
|
2
|
+
/* eslint-disable func-names */
|
|
3
|
+
/* eslint-disable consistent-return */
|
|
4
|
+
const { DataStore } = require('@abtnode/db/lib/base');
|
|
5
|
+
|
|
6
|
+
class NedbStore {
|
|
7
|
+
constructor(dbPath) {
|
|
8
|
+
this.dbPath = dbPath;
|
|
9
|
+
this.db = new DataStore({
|
|
10
|
+
filename: this.dbPath,
|
|
11
|
+
autoload: true,
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async isCancelled(id) {
|
|
16
|
+
const job = await this.db.findOne({ id });
|
|
17
|
+
return !!job && !!job.cancelled;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
getJob(id) {
|
|
21
|
+
return this.db.findOne({ id });
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
getJobs() {
|
|
25
|
+
return this.db
|
|
26
|
+
.cursor({ delay: { $exists: false } })
|
|
27
|
+
.sort({ createdAt: 1 })
|
|
28
|
+
.exec();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
getScheduledJobs() {
|
|
32
|
+
return this.db
|
|
33
|
+
.cursor({ delay: { $exists: true }, willRunAt: { $lte: Date.now() } })
|
|
34
|
+
.sort({ createdAt: 1 })
|
|
35
|
+
.exec();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async updateJob(id, updates) {
|
|
39
|
+
const job = await this.db.findOne({ id });
|
|
40
|
+
if (!job) {
|
|
41
|
+
throw new Error(`Job ${id} does not exist`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const update = { ...updates, updatedAt: Date.now() };
|
|
45
|
+
await this.db.update({ id }, { $set: update });
|
|
46
|
+
return Object.assign(job, update);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async addJob(id, job, attrs = {}) {
|
|
50
|
+
const exist = await this.db.findOne({ id });
|
|
51
|
+
if (exist) {
|
|
52
|
+
throw new Error(`Job ${id} already exist`);
|
|
53
|
+
}
|
|
54
|
+
return this.db.insert({
|
|
55
|
+
id,
|
|
56
|
+
job,
|
|
57
|
+
retryCount: 1,
|
|
58
|
+
cancelled: false,
|
|
59
|
+
...attrs,
|
|
60
|
+
createdAt: Date.now(),
|
|
61
|
+
updatedAt: Date.now(),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async deleteJob(id) {
|
|
66
|
+
return this.db.remove({ id });
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
loadDatabase(cb) {
|
|
70
|
+
this.db.loadDatabase(cb);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
module.exports = NedbStore;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
class SequelizeStore {
|
|
2
|
+
constructor(db, queue) {
|
|
3
|
+
this.db = db;
|
|
4
|
+
this.queue = queue;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
async isCancelled(id) {
|
|
8
|
+
const job = await this.db.findOne({ queue: this.queue, id });
|
|
9
|
+
return !!job && !!job.cancelled;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
getJob(id) {
|
|
13
|
+
return this.db.findOne({ queue: this.queue, id });
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
getJobs() {
|
|
17
|
+
return this.db.find({ queue: this.queue, delay: { $exists: false } }, {}, { createdAt: 1 });
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
getScheduledJobs() {
|
|
21
|
+
return this.db.find(
|
|
22
|
+
{ queue: this.queue, delay: { $exists: true }, willRunAt: { $lte: Date.now() } },
|
|
23
|
+
{},
|
|
24
|
+
{ createdAt: 1 }
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async updateJob(id, updates) {
|
|
29
|
+
const job = await this.db.findOne({ queue: this.queue, id });
|
|
30
|
+
if (!job) {
|
|
31
|
+
throw new Error(`Job ${id} does not exist`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const update = { ...updates, updatedAt: Date.now() };
|
|
35
|
+
await this.db.update({ queue: this.queue, id }, { $set: update });
|
|
36
|
+
return Object.assign(job, update);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async addJob(id, job, attrs = {}) {
|
|
40
|
+
const exist = await this.db.findOne({ queue: this.queue, id });
|
|
41
|
+
if (exist) {
|
|
42
|
+
throw new Error(`Job ${id} already exist`);
|
|
43
|
+
}
|
|
44
|
+
return this.db.insert({
|
|
45
|
+
id,
|
|
46
|
+
job,
|
|
47
|
+
queue: this.queue,
|
|
48
|
+
retryCount: 1,
|
|
49
|
+
cancelled: false,
|
|
50
|
+
...attrs,
|
|
51
|
+
createdAt: Date.now(),
|
|
52
|
+
updatedAt: Date.now(),
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async deleteJob(id) {
|
|
57
|
+
return this.db.remove({ queue: this.queue, id });
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
loadDatabase(cb) {
|
|
61
|
+
return this.db.loadDatabase(cb);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
module.exports = SequelizeStore;
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.16.8-
|
|
6
|
+
"version": "1.16.8-next-d1e52353",
|
|
7
7
|
"description": "",
|
|
8
8
|
"main": "lib/index.js",
|
|
9
9
|
"files": [
|
|
@@ -13,19 +13,19 @@
|
|
|
13
13
|
"lint": "eslint tests lib",
|
|
14
14
|
"lint:fix": "eslint --fix tests lib",
|
|
15
15
|
"test": "node tools/jest.js",
|
|
16
|
-
"coverage": "npm run test -- --coverage"
|
|
16
|
+
"coverage": "npm run test -- --coverage --runInBand"
|
|
17
17
|
},
|
|
18
18
|
"keywords": [],
|
|
19
19
|
"author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
|
|
20
20
|
"license": "MIT",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@abtnode/db": "1.16.8-
|
|
23
|
-
"@abtnode/util": "1.16.8-
|
|
22
|
+
"@abtnode/db": "1.16.8-next-d1e52353",
|
|
23
|
+
"@abtnode/util": "1.16.8-next-d1e52353",
|
|
24
24
|
"debug": "^4.3.4",
|
|
25
25
|
"fastq": "^1.13.0",
|
|
26
|
-
"uuid": "
|
|
26
|
+
"uuid": "^8.3.2"
|
|
27
27
|
},
|
|
28
|
-
"gitHead": "
|
|
28
|
+
"gitHead": "d357376aa3df9ef789befc7f548629deecb04d96",
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"jest": "^27.5.1"
|
|
31
31
|
}
|
package/lib/store.js
DELETED
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-underscore-dangle */
|
|
2
|
-
/* eslint-disable func-names */
|
|
3
|
-
/* eslint-disable consistent-return */
|
|
4
|
-
const { DataStore } = require('@abtnode/db/lib/base');
|
|
5
|
-
|
|
6
|
-
class JobStore {
|
|
7
|
-
constructor(dbPath) {
|
|
8
|
-
this.dbPath = dbPath;
|
|
9
|
-
this.db = new DataStore({
|
|
10
|
-
filename: this.dbPath,
|
|
11
|
-
autoload: true,
|
|
12
|
-
});
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
isCancelled(id) {
|
|
16
|
-
return new Promise((resolve, reject) => {
|
|
17
|
-
this.db.findOne({ _id: id }, (e, job) => {
|
|
18
|
-
if (e) return reject(e);
|
|
19
|
-
return resolve(!!job && !!job.cancelled);
|
|
20
|
-
});
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
getJob(id, cb) {
|
|
25
|
-
this.db.findOne({ _id: id }, cb);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
getJobs(cb) {
|
|
29
|
-
this.db
|
|
30
|
-
.cursor({ delay: { $exists: false } })
|
|
31
|
-
.sort({ createdAt: 1 })
|
|
32
|
-
.exec((err, result) => {
|
|
33
|
-
if (err) {
|
|
34
|
-
console.error('error find jobs', err);
|
|
35
|
-
}
|
|
36
|
-
cb(err, result);
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
getScheduledJobs() {
|
|
41
|
-
return this.db
|
|
42
|
-
.cursor({ delay: { $exists: true }, willRunAt: { $lte: Date.now() } })
|
|
43
|
-
.sort({ createdAt: 1 })
|
|
44
|
-
.exec();
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
updateJob(id, updates, cb) {
|
|
48
|
-
this.db.findOne({ _id: id }, (err, exist) => {
|
|
49
|
-
if (err) return cb(err);
|
|
50
|
-
if (!exist) return cb(new Error(`Job ${id} does not exist`));
|
|
51
|
-
|
|
52
|
-
const update = {
|
|
53
|
-
...updates,
|
|
54
|
-
updatedAt: Date.now(),
|
|
55
|
-
};
|
|
56
|
-
this.db.update(
|
|
57
|
-
{
|
|
58
|
-
_id: id,
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
$set: update,
|
|
62
|
-
},
|
|
63
|
-
(e) => {
|
|
64
|
-
if (e) {
|
|
65
|
-
console.error('error updating job', e);
|
|
66
|
-
return cb(e, null);
|
|
67
|
-
}
|
|
68
|
-
return cb(null, Object.assign(exist, update));
|
|
69
|
-
}
|
|
70
|
-
);
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
addJob(id, job, cb, attrs = {}) {
|
|
75
|
-
this.db.findOne({ _id: id }, (err, exist) => {
|
|
76
|
-
if (err) return cb(err);
|
|
77
|
-
if (exist) return new Error(`Job ${id} already exist`);
|
|
78
|
-
this.db.insert(
|
|
79
|
-
{
|
|
80
|
-
_id: id,
|
|
81
|
-
job,
|
|
82
|
-
retryCount: 1,
|
|
83
|
-
cancelled: false,
|
|
84
|
-
...attrs,
|
|
85
|
-
createdAt: Date.now(),
|
|
86
|
-
updatedAt: Date.now(),
|
|
87
|
-
},
|
|
88
|
-
(e) => {
|
|
89
|
-
if (e) console.error('error inserting job', e);
|
|
90
|
-
return cb(e);
|
|
91
|
-
}
|
|
92
|
-
);
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
deleteJob(id, cb) {
|
|
97
|
-
this.db.findOne({ _id: id }, (err) => {
|
|
98
|
-
if (err) return cb(err);
|
|
99
|
-
this.db.remove({ _id: id }, {}, (e) => cb(e));
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
module.exports = JobStore;
|