bullmq 5.12.12 → 5.12.14

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.
Files changed (50) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +0 -10
  3. package/dist/cjs/classes/queue.js +1 -1
  4. package/dist/cjs/classes/queue.js.map +1 -1
  5. package/dist/cjs/classes/repeat.js +28 -22
  6. package/dist/cjs/classes/repeat.js.map +1 -1
  7. package/dist/cjs/classes/scripts.js +18 -5
  8. package/dist/cjs/classes/scripts.js.map +1 -1
  9. package/dist/cjs/classes/worker.js +3 -1
  10. package/dist/cjs/classes/worker.js.map +1 -1
  11. package/dist/cjs/commands/{addRepeatableJob-1.lua → addRepeatableJob-2.lua} +26 -15
  12. package/dist/cjs/commands/includes/collectMetrics.lua +1 -1
  13. package/dist/cjs/commands/updateRepeatableJobMillis-1.lua +28 -0
  14. package/dist/cjs/scripts/addRepeatableJob-2.js +228 -0
  15. package/dist/cjs/scripts/addRepeatableJob-2.js.map +1 -0
  16. package/dist/cjs/scripts/index.js +2 -1
  17. package/dist/cjs/scripts/index.js.map +1 -1
  18. package/dist/cjs/scripts/moveToFinished-14.js +1 -1
  19. package/dist/cjs/scripts/updateRepeatableJobMillis-1.js +33 -0
  20. package/dist/cjs/scripts/updateRepeatableJobMillis-1.js.map +1 -0
  21. package/dist/cjs/tsconfig-cjs.tsbuildinfo +1 -1
  22. package/dist/esm/classes/queue.js +1 -1
  23. package/dist/esm/classes/queue.js.map +1 -1
  24. package/dist/esm/classes/repeat.d.ts +3 -1
  25. package/dist/esm/classes/repeat.js +28 -22
  26. package/dist/esm/classes/repeat.js.map +1 -1
  27. package/dist/esm/classes/scripts.d.ts +3 -2
  28. package/dist/esm/classes/scripts.js +18 -5
  29. package/dist/esm/classes/scripts.js.map +1 -1
  30. package/dist/esm/classes/worker.js +3 -1
  31. package/dist/esm/classes/worker.js.map +1 -1
  32. package/dist/esm/commands/{addRepeatableJob-1.lua → addRepeatableJob-2.lua} +26 -15
  33. package/dist/esm/commands/includes/collectMetrics.lua +1 -1
  34. package/dist/esm/commands/updateRepeatableJobMillis-1.lua +28 -0
  35. package/dist/esm/scripts/addRepeatableJob-2.js +225 -0
  36. package/dist/esm/scripts/addRepeatableJob-2.js.map +1 -0
  37. package/dist/esm/scripts/index.d.ts +2 -1
  38. package/dist/esm/scripts/index.js +2 -1
  39. package/dist/esm/scripts/index.js.map +1 -1
  40. package/dist/esm/scripts/moveToFinished-14.js +1 -1
  41. package/dist/esm/scripts/updateRepeatableJobMillis-1.d.ts +5 -0
  42. package/dist/esm/scripts/updateRepeatableJobMillis-1.js +30 -0
  43. package/dist/esm/scripts/updateRepeatableJobMillis-1.js.map +1 -0
  44. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  45. package/package.json +1 -1
  46. package/dist/cjs/scripts/addRepeatableJob-1.js +0 -67
  47. package/dist/cjs/scripts/addRepeatableJob-1.js.map +0 -1
  48. package/dist/esm/scripts/addRepeatableJob-1.js +0 -64
  49. package/dist/esm/scripts/addRepeatableJob-1.js.map +0 -1
  50. /package/dist/esm/scripts/{addRepeatableJob-1.d.ts → addRepeatableJob-2.d.ts} +0 -0
@@ -0,0 +1,225 @@
1
+ const content = `--[[
2
+ Adds a repeatable job
3
+ Input:
4
+ KEYS[1] 'repeat' key
5
+ KEYS[2] 'delayed' key
6
+ ARGV[1] next milliseconds
7
+ ARGV[2] msgpacked options
8
+ [1] name
9
+ [2] tz?
10
+ [3] patten?
11
+ [4] endDate?
12
+ [5] every?
13
+ ARGV[3] legacy custom key TODO: remove this logic in next breaking change
14
+ ARGV[4] custom key
15
+ ARGV[5] prefix key
16
+ Output:
17
+ repeatableKey - OK
18
+ ]]
19
+ local rcall = redis.call
20
+ local repeatKey = KEYS[1]
21
+ local delayedKey = KEYS[2]
22
+ local nextMillis = ARGV[1]
23
+ local legacyCustomKey = ARGV[3]
24
+ local customKey = ARGV[4]
25
+ local prefixKey = ARGV[5]
26
+ -- Includes
27
+ --[[
28
+ Function to remove job.
29
+ ]]
30
+ -- Includes
31
+ --[[
32
+ Function to remove debounce key.
33
+ ]]
34
+ local function removeDebounceKey(prefixKey, jobKey)
35
+ local debounceId = rcall("HGET", jobKey, "deid")
36
+ if debounceId then
37
+ local debounceKey = prefixKey .. "de:" .. debounceId
38
+ rcall("DEL", debounceKey)
39
+ end
40
+ end
41
+ --[[
42
+ Function to remove job keys.
43
+ ]]
44
+ local function removeJobKeys(jobKey)
45
+ return rcall("DEL", jobKey, jobKey .. ':logs',
46
+ jobKey .. ':dependencies', jobKey .. ':processed', jobKey .. ':failed')
47
+ end
48
+ --[[
49
+ Check if this job has a parent. If so we will just remove it from
50
+ the parent child list, but if it is the last child we should move the parent to "wait/paused"
51
+ which requires code from "moveToFinished"
52
+ ]]
53
+ -- Includes
54
+ --[[
55
+ Function to add job in target list and add marker if needed.
56
+ ]]
57
+ -- Includes
58
+ --[[
59
+ Add marker if needed when a job is available.
60
+ ]]
61
+ local function addBaseMarkerIfNeeded(markerKey, isPausedOrMaxed)
62
+ if not isPausedOrMaxed then
63
+ rcall("ZADD", markerKey, 0, "0")
64
+ end
65
+ end
66
+ local function addJobInTargetList(targetKey, markerKey, pushCmd, isPausedOrMaxed, jobId)
67
+ rcall(pushCmd, targetKey, jobId)
68
+ addBaseMarkerIfNeeded(markerKey, isPausedOrMaxed)
69
+ end
70
+ --[[
71
+ Functions to destructure job key.
72
+ Just a bit of warning, these functions may be a bit slow and affect performance significantly.
73
+ ]]
74
+ local getJobIdFromKey = function (jobKey)
75
+ return string.match(jobKey, ".*:(.*)")
76
+ end
77
+ local getJobKeyPrefix = function (jobKey, jobId)
78
+ return string.sub(jobKey, 0, #jobKey - #jobId)
79
+ end
80
+ --[[
81
+ Function to check for the meta.paused key to decide if we are paused or not
82
+ (since an empty list and !EXISTS are not really the same).
83
+ ]]
84
+ local function getTargetQueueList(queueMetaKey, activeKey, waitKey, pausedKey)
85
+ local queueAttributes = rcall("HMGET", queueMetaKey, "paused", "concurrency")
86
+ if queueAttributes[1] then
87
+ return pausedKey, true
88
+ else
89
+ if queueAttributes[2] then
90
+ local activeCount = rcall("LLEN", activeKey)
91
+ if activeCount >= tonumber(queueAttributes[2]) then
92
+ return waitKey, true
93
+ else
94
+ return waitKey, false
95
+ end
96
+ end
97
+ end
98
+ return waitKey, false
99
+ end
100
+ local function moveParentToWait(parentPrefix, parentId, emitEvent)
101
+ local parentTarget, isPausedOrMaxed = getTargetQueueList(parentPrefix .. "meta", parentPrefix .. "active",
102
+ parentPrefix .. "wait", parentPrefix .. "paused")
103
+ addJobInTargetList(parentTarget, parentPrefix .. "marker", "RPUSH", isPausedOrMaxed, parentId)
104
+ if emitEvent then
105
+ local parentEventStream = parentPrefix .. "events"
106
+ rcall("XADD", parentEventStream, "*", "event", "waiting", "jobId", parentId, "prev", "waiting-children")
107
+ end
108
+ end
109
+ local function removeParentDependencyKey(jobKey, hard, parentKey, baseKey, debounceId)
110
+ if parentKey then
111
+ local parentDependenciesKey = parentKey .. ":dependencies"
112
+ local result = rcall("SREM", parentDependenciesKey, jobKey)
113
+ if result > 0 then
114
+ local pendingDependencies = rcall("SCARD", parentDependenciesKey)
115
+ if pendingDependencies == 0 then
116
+ local parentId = getJobIdFromKey(parentKey)
117
+ local parentPrefix = getJobKeyPrefix(parentKey, parentId)
118
+ local numRemovedElements = rcall("ZREM", parentPrefix .. "waiting-children", parentId)
119
+ if numRemovedElements == 1 then
120
+ if hard then -- remove parent in same queue
121
+ if parentPrefix == baseKey then
122
+ removeParentDependencyKey(parentKey, hard, nil, baseKey, nil)
123
+ removeJobKeys(parentKey)
124
+ if debounceId then
125
+ rcall("DEL", parentPrefix .. "de:" .. debounceId)
126
+ end
127
+ else
128
+ moveParentToWait(parentPrefix, parentId)
129
+ end
130
+ else
131
+ moveParentToWait(parentPrefix, parentId, true)
132
+ end
133
+ end
134
+ end
135
+ return true
136
+ end
137
+ else
138
+ local parentAttributes = rcall("HMGET", jobKey, "parentKey", "deid")
139
+ local missedParentKey = parentAttributes[1]
140
+ if( (type(missedParentKey) == "string") and missedParentKey ~= ""
141
+ and (rcall("EXISTS", missedParentKey) == 1)) then
142
+ local parentDependenciesKey = missedParentKey .. ":dependencies"
143
+ local result = rcall("SREM", parentDependenciesKey, jobKey)
144
+ if result > 0 then
145
+ local pendingDependencies = rcall("SCARD", parentDependenciesKey)
146
+ if pendingDependencies == 0 then
147
+ local parentId = getJobIdFromKey(missedParentKey)
148
+ local parentPrefix = getJobKeyPrefix(missedParentKey, parentId)
149
+ local numRemovedElements = rcall("ZREM", parentPrefix .. "waiting-children", parentId)
150
+ if numRemovedElements == 1 then
151
+ if hard then
152
+ if parentPrefix == baseKey then
153
+ removeParentDependencyKey(missedParentKey, hard, nil, baseKey, nil)
154
+ removeJobKeys(missedParentKey)
155
+ if parentAttributes[2] then
156
+ rcall("DEL", parentPrefix .. "de:" .. parentAttributes[2])
157
+ end
158
+ else
159
+ moveParentToWait(parentPrefix, parentId)
160
+ end
161
+ else
162
+ moveParentToWait(parentPrefix, parentId, true)
163
+ end
164
+ end
165
+ end
166
+ return true
167
+ end
168
+ end
169
+ end
170
+ return false
171
+ end
172
+ local function removeJob(jobId, hard, baseKey, shouldRemoveDebounceKey)
173
+ local jobKey = baseKey .. jobId
174
+ removeParentDependencyKey(jobKey, hard, nil, baseKey)
175
+ if shouldRemoveDebounceKey then
176
+ removeDebounceKey(baseKey, jobKey)
177
+ end
178
+ removeJobKeys(jobKey)
179
+ end
180
+ local function storeRepeatableJob(repeatKey, customKey, nextMillis, rawOpts)
181
+ rcall("ZADD", repeatKey, nextMillis, customKey)
182
+ local opts = cmsgpack.unpack(rawOpts)
183
+ local optionalValues = {}
184
+ if opts['tz'] then
185
+ table.insert(optionalValues, "tz")
186
+ table.insert(optionalValues, opts['tz'])
187
+ end
188
+ if opts['pattern'] then
189
+ table.insert(optionalValues, "pattern")
190
+ table.insert(optionalValues, opts['pattern'])
191
+ end
192
+ if opts['endDate'] then
193
+ table.insert(optionalValues, "endDate")
194
+ table.insert(optionalValues, opts['endDate'])
195
+ end
196
+ if opts['every'] then
197
+ table.insert(optionalValues, "every")
198
+ table.insert(optionalValues, opts['every'])
199
+ end
200
+ rcall("HMSET", repeatKey .. ":" .. customKey, "name", opts['name'],
201
+ unpack(optionalValues))
202
+ return customKey
203
+ end
204
+ -- If we are overriding a repeatable job we must delete the delayed job for
205
+ -- the next iteration.
206
+ local prevMillis = rcall("ZSCORE", repeatKey, customKey)
207
+ if prevMillis ~= false then
208
+ local delayedJobId = "repeat:" .. customKey .. ":" .. prevMillis
209
+ if rcall("ZSCORE", delayedKey, delayedJobId) ~= false then
210
+ removeJob(delayedJobId, true, prefixKey, true --[[remove debounce key]])
211
+ rcall("ZREM", delayedKey, delayedJobId)
212
+ end
213
+ end
214
+ -- Keep backwards compatibility with old repeatable jobs (<= 3.0.0)
215
+ if rcall("ZSCORE", repeatKey, legacyCustomKey) ~= false then
216
+ return storeRepeatableJob(repeatKey, legacyCustomKey, nextMillis, ARGV[2])
217
+ end
218
+ return storeRepeatableJob(repeatKey, customKey, nextMillis, ARGV[2])
219
+ `;
220
+ export const addRepeatableJob = {
221
+ name: 'addRepeatableJob',
222
+ content,
223
+ keys: 2,
224
+ };
225
+ //# sourceMappingURL=addRepeatableJob-2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"addRepeatableJob-2.js","sourceRoot":"","sources":["../../../src/scripts/addRepeatableJob-2.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0Nf,CAAC;AACF,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,IAAI,EAAE,kBAAkB;IACxB,OAAO;IACP,IAAI,EAAE,CAAC;CACR,CAAC"}
@@ -2,7 +2,7 @@ export * from './addDelayedJob-6';
2
2
  export * from './addLog-2';
3
3
  export * from './addParentJob-4';
4
4
  export * from './addPrioritizedJob-8';
5
- export * from './addRepeatableJob-1';
5
+ export * from './addRepeatableJob-2';
6
6
  export * from './addStandardJob-8';
7
7
  export * from './changeDelay-4';
8
8
  export * from './changePriority-7';
@@ -38,3 +38,4 @@ export * from './retryJob-11';
38
38
  export * from './saveStacktrace-1';
39
39
  export * from './updateData-1';
40
40
  export * from './updateProgress-3';
41
+ export * from './updateRepeatableJobMillis-1';
@@ -2,7 +2,7 @@ export * from './addDelayedJob-6';
2
2
  export * from './addLog-2';
3
3
  export * from './addParentJob-4';
4
4
  export * from './addPrioritizedJob-8';
5
- export * from './addRepeatableJob-1';
5
+ export * from './addRepeatableJob-2';
6
6
  export * from './addStandardJob-8';
7
7
  export * from './changeDelay-4';
8
8
  export * from './changePriority-7';
@@ -38,4 +38,5 @@ export * from './retryJob-11';
38
38
  export * from './saveStacktrace-1';
39
39
  export * from './updateData-1';
40
40
  export * from './updateProgress-3';
41
+ export * from './updateRepeatableJobMillis-1';
41
42
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/scripts/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,0BAA0B,CAAC;AACzC,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/scripts/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,0BAA0B,CAAC;AACzC,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,+BAA+B,CAAC"}
@@ -78,7 +78,7 @@ local function collectMetrics(metaKey, dataPointsList, maxDataPoints,
78
78
  rcall("HSET", metaKey, "prevTS", timestamp, "prevCount", 0)
79
79
  return
80
80
  end
81
- local N = math.floor((timestamp - prevTS) / 60000)
81
+ local N = math.min(math.floor((timestamp - prevTS) / 60000), tonumber(maxDataPoints))
82
82
  if N > 0 then
83
83
  local delta = count - rcall("HGET", metaKey, "prevCount")
84
84
  -- If N > 1, add N-1 zeros to the list
@@ -0,0 +1,5 @@
1
+ export declare const updateRepeatableJobMillis: {
2
+ name: string;
3
+ content: string;
4
+ keys: number;
5
+ };
@@ -0,0 +1,30 @@
1
+ const content = `--[[
2
+ Adds a repeatable job
3
+ Input:
4
+ KEYS[1] 'repeat' key
5
+ ARGV[1] next milliseconds
6
+ ARGV[2] custom key
7
+ ARGV[3] legacy custom key TODO: remove this logic in next breaking change
8
+ Output:
9
+ repeatableKey - OK
10
+ ]]
11
+ local rcall = redis.call
12
+ local repeatKey = KEYS[1]
13
+ local nextMillis = ARGV[1]
14
+ local customKey = ARGV[2]
15
+ local legacyCustomKey = ARGV[3]
16
+ if rcall("ZSCORE", repeatKey, customKey) ~= false then
17
+ rcall("ZADD", repeatKey, nextMillis, customKey)
18
+ return customKey
19
+ elseif rcall("ZSCORE", repeatKey, legacyCustomKey) ~= false then
20
+ rcall("ZADD", repeatKey, nextMillis, legacyCustomKey)
21
+ return legacyCustomKey
22
+ end
23
+ return ''
24
+ `;
25
+ export const updateRepeatableJobMillis = {
26
+ name: 'updateRepeatableJobMillis',
27
+ content,
28
+ keys: 1,
29
+ };
30
+ //# sourceMappingURL=updateRepeatableJobMillis-1.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"updateRepeatableJobMillis-1.js","sourceRoot":"","sources":["../../../src/scripts/updateRepeatableJobMillis-1.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,GAAG;;;;;;;;;;;;;;;;;;;;;;;CAuBf,CAAC;AACF,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,IAAI,EAAE,2BAA2B;IACjC,OAAO;IACP,IAAI,EAAE,CAAC;CACR,CAAC"}