1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118 | 1
1
1
1
1
297
297
297
297
297
297
1
1
151
151
151
1
151
151
151
151
1
150
1
142
142
142
142
142
142
142
142
1
5
1
4
4
1
4
1
3
3
1
2
2
2
1
1
1
1
2
2
1
1
1
1
2
2
2
1
| var events = require('events');
var util = require('util');
var helpers = require('./helpers');
var lua = require('./lua');
function Job(queue, jobId, data, options) {
this.queue = queue;
this.id = jobId;
this.progress = 0;
this.data = data || {};
this.options = options || {};
this.status = 'created';
}
util.inherits(Job, events.EventEmitter);
Job.fromId = function (queue, jobId, cb) {
queue.client.hget(queue.toKey('jobs'), jobId, function (err, data) {
/* istanbul ignore if */
Iif (err) return cb(err);
return cb(null, Job.fromData(queue, jobId, data));
});
};
Job.fromData = function (queue, jobId, data) {
// no need for try-catch here since we made the JSON ourselves in job#toData
data = JSON.parse(data);
var job = new Job(queue, jobId, data.data, data.options);
job.status = data.status;
return job;
};
Job.prototype.toData = function () {
return JSON.stringify({
data: this.data,
options: this.options,
status: this.status
});
};
Job.prototype.save = function (cb) {
cb = cb || helpers.defaultCb;
var self = this;
this.queue.client.evalsha(lua.shas.addJob, 3,
this.queue.toKey('id'), this.queue.toKey('jobs'), this.queue.toKey('waiting'),
this.toData(),
function (err, jobId) {
/* istanbul ignore if */
Iif (err) return cb(err);
self.id = jobId;
self.queue.jobs[jobId] = self;
return cb(null, self);
}
);
return this;
};
Job.prototype.retries = function (n) {
if (n < 0) {
throw Error('Retries cannot be negative');
}
this.options.retries = n;
return this;
};
Job.prototype.timeout = function (ms) {
if (ms < 0) {
throw Error('Timeout cannot be negative');
}
this.options.timeout = ms;
return this;
};
Job.prototype.reportProgress = function (progress, cb) {
// right now we just send the pubsub event
// might consider also updating the job hash for persistence
cb = cb || helpers.defaultCb;
progress = Number(progress);
if (progress < 0 || progress > 100) {
return process.nextTick(cb.bind(null, Error('Progress must be between 0 and 100')));
}
this.progress = progress;
this.queue.client.publish(this.queue.toKey('events'), JSON.stringify({
id: this.id,
event: 'progress',
data: progress
}), cb);
};
Job.prototype.remove = function (cb) {
cb = cb || helpers.defaultCb;
this.queue.client.evalsha(lua.shas.removeJob, 6,
this.queue.toKey('succeeded'), this.queue.toKey('failed'), this.queue.toKey('waiting'),
this.queue.toKey('active'), this.queue.toKey('stalling'), this.queue.toKey('jobs'),
this.id,
cb
);
};
Job.prototype.retry = function (cb) {
cb = cb || helpers.defaultCb;
this.queue.client.multi()
.srem(this.queue.toKey('failed'), this.id)
.lpush(this.queue.toKey('waiting'), this.id)
.exec(cb);
};
Job.prototype.isInSet = function (set, cb) {
this.queue.client.sismember(this.queue.toKey(set), this.id, function (err, result) {
/* istanbul ignore if */
Iif (err) return cb(err);
return cb(null, result === 1);
});
};
module.exports = Job;
|