@quave/agenda 1.0.0

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 (216) hide show
  1. package/LICENSE.md +25 -0
  2. package/README.md +380 -0
  3. package/dist/Job.d.ts +190 -0
  4. package/dist/Job.js +689 -0
  5. package/dist/Job.js.map +1 -0
  6. package/dist/JobProcessingQueue.d.ts +47 -0
  7. package/dist/JobProcessingQueue.js +107 -0
  8. package/dist/JobProcessingQueue.js.map +1 -0
  9. package/dist/JobProcessor.d.ts +72 -0
  10. package/dist/JobProcessor.js +512 -0
  11. package/dist/JobProcessor.js.map +1 -0
  12. package/dist/backends/index.d.ts +18 -0
  13. package/dist/backends/index.js +20 -0
  14. package/dist/backends/index.js.map +1 -0
  15. package/dist/cjs/Job.d.ts +190 -0
  16. package/dist/cjs/Job.js +696 -0
  17. package/dist/cjs/Job.js.map +1 -0
  18. package/dist/cjs/JobProcessingQueue.d.ts +47 -0
  19. package/dist/cjs/JobProcessingQueue.js +111 -0
  20. package/dist/cjs/JobProcessingQueue.js.map +1 -0
  21. package/dist/cjs/JobProcessor.d.ts +72 -0
  22. package/dist/cjs/JobProcessor.js +519 -0
  23. package/dist/cjs/JobProcessor.js.map +1 -0
  24. package/dist/cjs/backends/index.d.ts +17 -0
  25. package/dist/cjs/backends/index.js +20 -0
  26. package/dist/cjs/backends/index.js.map +1 -0
  27. package/dist/cjs/decorators/Define.d.ts +33 -0
  28. package/dist/cjs/decorators/Define.js +47 -0
  29. package/dist/cjs/decorators/Define.js.map +1 -0
  30. package/dist/cjs/decorators/Every.d.ts +43 -0
  31. package/dist/cjs/decorators/Every.js +58 -0
  32. package/dist/cjs/decorators/Every.js.map +1 -0
  33. package/dist/cjs/decorators/JobsController.d.ts +43 -0
  34. package/dist/cjs/decorators/JobsController.js +40 -0
  35. package/dist/cjs/decorators/JobsController.js.map +1 -0
  36. package/dist/cjs/decorators/index.d.ts +41 -0
  37. package/dist/cjs/decorators/index.js +57 -0
  38. package/dist/cjs/decorators/index.js.map +1 -0
  39. package/dist/cjs/decorators/metadata.d.ts +50 -0
  40. package/dist/cjs/decorators/metadata.js +41 -0
  41. package/dist/cjs/decorators/metadata.js.map +1 -0
  42. package/dist/cjs/decorators/register.d.ts +52 -0
  43. package/dist/cjs/decorators/register.js +145 -0
  44. package/dist/cjs/decorators/register.js.map +1 -0
  45. package/dist/cjs/index.d.ts +498 -0
  46. package/dist/cjs/index.js +776 -0
  47. package/dist/cjs/index.js.map +1 -0
  48. package/dist/cjs/notifications/BaseNotificationChannel.d.ts +47 -0
  49. package/dist/cjs/notifications/BaseNotificationChannel.js +112 -0
  50. package/dist/cjs/notifications/BaseNotificationChannel.js.map +1 -0
  51. package/dist/cjs/notifications/InMemoryNotificationChannel.d.ts +13 -0
  52. package/dist/cjs/notifications/InMemoryNotificationChannel.js +37 -0
  53. package/dist/cjs/notifications/InMemoryNotificationChannel.js.map +1 -0
  54. package/dist/cjs/notifications/index.d.ts +2 -0
  55. package/dist/cjs/notifications/index.js +8 -0
  56. package/dist/cjs/notifications/index.js.map +1 -0
  57. package/dist/cjs/package.json +1 -0
  58. package/dist/cjs/types/AgendaBackend.d.ts +61 -0
  59. package/dist/cjs/types/AgendaBackend.js +3 -0
  60. package/dist/cjs/types/AgendaBackend.js.map +1 -0
  61. package/dist/cjs/types/AgendaConfig.d.ts +10 -0
  62. package/dist/cjs/types/AgendaConfig.js +3 -0
  63. package/dist/cjs/types/AgendaConfig.js.map +1 -0
  64. package/dist/cjs/types/AgendaStatus.d.ts +32 -0
  65. package/dist/cjs/types/AgendaStatus.js +3 -0
  66. package/dist/cjs/types/AgendaStatus.js.map +1 -0
  67. package/dist/cjs/types/DbOptions.d.ts +4 -0
  68. package/dist/cjs/types/DbOptions.js +3 -0
  69. package/dist/cjs/types/DbOptions.js.map +1 -0
  70. package/dist/cjs/types/DrainOptions.d.ts +37 -0
  71. package/dist/cjs/types/DrainOptions.js +3 -0
  72. package/dist/cjs/types/DrainOptions.js.map +1 -0
  73. package/dist/cjs/types/JobDefinition.d.ts +49 -0
  74. package/dist/cjs/types/JobDefinition.js +3 -0
  75. package/dist/cjs/types/JobDefinition.js.map +1 -0
  76. package/dist/cjs/types/JobLogger.d.ts +111 -0
  77. package/dist/cjs/types/JobLogger.js +3 -0
  78. package/dist/cjs/types/JobLogger.js.map +1 -0
  79. package/dist/cjs/types/JobParameters.d.ts +106 -0
  80. package/dist/cjs/types/JobParameters.js +21 -0
  81. package/dist/cjs/types/JobParameters.js.map +1 -0
  82. package/dist/cjs/types/JobQuery.d.ts +79 -0
  83. package/dist/cjs/types/JobQuery.js +36 -0
  84. package/dist/cjs/types/JobQuery.js.map +1 -0
  85. package/dist/cjs/types/JobRepository.d.ts +101 -0
  86. package/dist/cjs/types/JobRepository.js +3 -0
  87. package/dist/cjs/types/JobRepository.js.map +1 -0
  88. package/dist/cjs/types/NotificationChannel.d.ts +120 -0
  89. package/dist/cjs/types/NotificationChannel.js +3 -0
  90. package/dist/cjs/types/NotificationChannel.js.map +1 -0
  91. package/dist/cjs/utils/backoff.d.ts +152 -0
  92. package/dist/cjs/utils/backoff.js +175 -0
  93. package/dist/cjs/utils/backoff.js.map +1 -0
  94. package/dist/cjs/utils/dateConstraints.d.ts +48 -0
  95. package/dist/cjs/utils/dateConstraints.js +127 -0
  96. package/dist/cjs/utils/dateConstraints.js.map +1 -0
  97. package/dist/cjs/utils/isValidDate.d.ts +1 -0
  98. package/dist/cjs/utils/isValidDate.js +8 -0
  99. package/dist/cjs/utils/isValidDate.js.map +1 -0
  100. package/dist/cjs/utils/nextRunAt.d.ts +10 -0
  101. package/dist/cjs/utils/nextRunAt.js +119 -0
  102. package/dist/cjs/utils/nextRunAt.js.map +1 -0
  103. package/dist/cjs/utils/priority.d.ts +13 -0
  104. package/dist/cjs/utils/priority.js +23 -0
  105. package/dist/cjs/utils/priority.js.map +1 -0
  106. package/dist/cjs/utils/processEvery.d.ts +1 -0
  107. package/dist/cjs/utils/processEvery.js +13 -0
  108. package/dist/cjs/utils/processEvery.js.map +1 -0
  109. package/dist/cjs/utils/stack.d.ts +1 -0
  110. package/dist/cjs/utils/stack.js +21 -0
  111. package/dist/cjs/utils/stack.js.map +1 -0
  112. package/dist/cjs/version.d.ts +9 -0
  113. package/dist/cjs/version.js +13 -0
  114. package/dist/cjs/version.js.map +1 -0
  115. package/dist/decorators/Define.d.ts +33 -0
  116. package/dist/decorators/Define.js +44 -0
  117. package/dist/decorators/Define.js.map +1 -0
  118. package/dist/decorators/Every.d.ts +43 -0
  119. package/dist/decorators/Every.js +55 -0
  120. package/dist/decorators/Every.js.map +1 -0
  121. package/dist/decorators/JobsController.d.ts +43 -0
  122. package/dist/decorators/JobsController.js +37 -0
  123. package/dist/decorators/JobsController.js.map +1 -0
  124. package/dist/decorators/index.d.ts +41 -0
  125. package/dist/decorators/index.js +46 -0
  126. package/dist/decorators/index.js.map +1 -0
  127. package/dist/decorators/metadata.d.ts +50 -0
  128. package/dist/decorators/metadata.js +35 -0
  129. package/dist/decorators/metadata.js.map +1 -0
  130. package/dist/decorators/register.d.ts +52 -0
  131. package/dist/decorators/register.js +139 -0
  132. package/dist/decorators/register.js.map +1 -0
  133. package/dist/index.d.ts +498 -0
  134. package/dist/index.js +744 -0
  135. package/dist/index.js.map +1 -0
  136. package/dist/notifications/BaseNotificationChannel.d.ts +47 -0
  137. package/dist/notifications/BaseNotificationChannel.js +108 -0
  138. package/dist/notifications/BaseNotificationChannel.js.map +1 -0
  139. package/dist/notifications/InMemoryNotificationChannel.d.ts +13 -0
  140. package/dist/notifications/InMemoryNotificationChannel.js +33 -0
  141. package/dist/notifications/InMemoryNotificationChannel.js.map +1 -0
  142. package/dist/notifications/index.d.ts +2 -0
  143. package/dist/notifications/index.js +3 -0
  144. package/dist/notifications/index.js.map +1 -0
  145. package/dist/types/AgendaBackend.d.ts +61 -0
  146. package/dist/types/AgendaBackend.js +2 -0
  147. package/dist/types/AgendaBackend.js.map +1 -0
  148. package/dist/types/AgendaConfig.d.ts +10 -0
  149. package/dist/types/AgendaConfig.js +2 -0
  150. package/dist/types/AgendaConfig.js.map +1 -0
  151. package/dist/types/AgendaStatus.d.ts +32 -0
  152. package/dist/types/AgendaStatus.js +2 -0
  153. package/dist/types/AgendaStatus.js.map +1 -0
  154. package/dist/types/DbOptions.d.ts +4 -0
  155. package/dist/types/DbOptions.js +2 -0
  156. package/dist/types/DbOptions.js.map +1 -0
  157. package/dist/types/DrainOptions.d.ts +37 -0
  158. package/dist/types/DrainOptions.js +2 -0
  159. package/dist/types/DrainOptions.js.map +1 -0
  160. package/dist/types/JobDefinition.d.ts +49 -0
  161. package/dist/types/JobDefinition.js +2 -0
  162. package/dist/types/JobDefinition.js.map +1 -0
  163. package/dist/types/JobLogger.d.ts +111 -0
  164. package/dist/types/JobLogger.js +2 -0
  165. package/dist/types/JobLogger.js.map +1 -0
  166. package/dist/types/JobParameters.d.ts +106 -0
  167. package/dist/types/JobParameters.js +17 -0
  168. package/dist/types/JobParameters.js.map +1 -0
  169. package/dist/types/JobQuery.d.ts +79 -0
  170. package/dist/types/JobQuery.js +33 -0
  171. package/dist/types/JobQuery.js.map +1 -0
  172. package/dist/types/JobRepository.d.ts +101 -0
  173. package/dist/types/JobRepository.js +2 -0
  174. package/dist/types/JobRepository.js.map +1 -0
  175. package/dist/types/NotificationChannel.d.ts +120 -0
  176. package/dist/types/NotificationChannel.js +2 -0
  177. package/dist/types/NotificationChannel.js.map +1 -0
  178. package/dist/utils/backoff.d.ts +152 -0
  179. package/dist/utils/backoff.js +167 -0
  180. package/dist/utils/backoff.js.map +1 -0
  181. package/dist/utils/dateConstraints.d.ts +48 -0
  182. package/dist/utils/dateConstraints.js +117 -0
  183. package/dist/utils/dateConstraints.js.map +1 -0
  184. package/dist/utils/isValidDate.d.ts +1 -0
  185. package/dist/utils/isValidDate.js +5 -0
  186. package/dist/utils/isValidDate.js.map +1 -0
  187. package/dist/utils/nextRunAt.d.ts +10 -0
  188. package/dist/utils/nextRunAt.js +110 -0
  189. package/dist/utils/nextRunAt.js.map +1 -0
  190. package/dist/utils/priority.d.ts +13 -0
  191. package/dist/utils/priority.js +20 -0
  192. package/dist/utils/priority.js.map +1 -0
  193. package/dist/utils/processEvery.d.ts +1 -0
  194. package/dist/utils/processEvery.js +7 -0
  195. package/dist/utils/processEvery.js.map +1 -0
  196. package/dist/utils/stack.d.ts +1 -0
  197. package/dist/utils/stack.js +18 -0
  198. package/dist/utils/stack.js.map +1 -0
  199. package/dist/version.d.ts +9 -0
  200. package/dist/version.js +10 -0
  201. package/dist/version.js.map +1 -0
  202. package/package.json +79 -0
  203. package/test/fixtures/forkHelper.js +40 -0
  204. package/test/fixtures/someJobDefinition.ts +12 -0
  205. package/test/shared/agenda-test-suite.ts +1876 -0
  206. package/test/shared/backoff-test-suite.ts +408 -0
  207. package/test/shared/debounce-test-suite.ts +377 -0
  208. package/test/shared/full-test-suite.ts +161 -0
  209. package/test/shared/index.ts +50 -0
  210. package/test/shared/joblogger-test-suite.ts +305 -0
  211. package/test/shared/jobprocessor-test-suite.ts +266 -0
  212. package/test/shared/notification-channel-test-suite.ts +471 -0
  213. package/test/shared/removeoncomplete-test-suite.ts +228 -0
  214. package/test/shared/repository-test-suite.ts +708 -0
  215. package/test/shared/retry-test-suite.ts +174 -0
  216. package/test/shared/test-utils.ts +100 -0
@@ -0,0 +1,512 @@
1
+ import debug from 'debug';
2
+ import { agendaVersion } from './version.js';
3
+ import { Job } from './Job.js';
4
+ import { JobProcessingQueue } from './JobProcessingQueue.js';
5
+ const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
6
+ const log = debug('agenda:jobProcessor');
7
+ const MAX_SAFE_32BIT_INTEGER = 2 ** 31; // Math.pow(2,31);
8
+ /**
9
+ * @class
10
+ * Process methods for jobs
11
+ */
12
+ export class JobProcessor {
13
+ async getStatus(fullDetails = false) {
14
+ const jobStatus = Object.keys(this.jobStatus).reduce((obj, key) => {
15
+ const status = this.jobStatus[key];
16
+ obj[key] = {
17
+ running: status?.running ?? 0,
18
+ locked: status?.locked ?? 0,
19
+ config: this.agenda.definitions[key]
20
+ };
21
+ return obj;
22
+ }, {});
23
+ return {
24
+ version: agendaVersion,
25
+ queueName: this.agenda.attrs.name,
26
+ totalQueueSizeDB: await this.agenda.db.getQueueSize(),
27
+ config: {
28
+ totalLockLimit: this.totalLockLimit,
29
+ maxConcurrency: this.maxConcurrency,
30
+ processEvery: this.processEvery
31
+ },
32
+ backend: {
33
+ // Placeholder - will be overwritten by Agenda.getRunningStats()
34
+ name: 'unknown',
35
+ hasNotificationChannel: false
36
+ },
37
+ internal: {
38
+ localQueueProcessing: this.localQueueProcessing
39
+ },
40
+ jobStatus,
41
+ queuedJobs: !fullDetails
42
+ ? this.jobQueue.length
43
+ : this.jobQueue.getQueue().map(job => ({
44
+ ...job.toJson(),
45
+ canceled: job.getCanceledMessage()
46
+ })),
47
+ runningJobs: !fullDetails
48
+ ? this.runningJobs.length
49
+ : this.runningJobs.map(job => ({
50
+ ...job.toJson(),
51
+ canceled: job.getCanceledMessage()
52
+ })),
53
+ lockedJobs: !fullDetails
54
+ ? this.lockedJobs.length
55
+ : this.lockedJobs.map(job => ({
56
+ ...job.toJson(),
57
+ canceled: job.getCanceledMessage()
58
+ }))
59
+ };
60
+ }
61
+ constructor(agenda, maxConcurrency, totalLockLimit, processEvery, notificationChannel) {
62
+ this.agenda = agenda;
63
+ this.maxConcurrency = maxConcurrency;
64
+ this.totalLockLimit = totalLockLimit;
65
+ this.processEvery = processEvery;
66
+ this.jobStatus = {};
67
+ this.localQueueProcessing = 0;
68
+ this.nextScanAt = new Date();
69
+ this.runningJobs = [];
70
+ this.lockedJobs = [];
71
+ this.isJobQueueFilling = new Map();
72
+ this.isRunning = true;
73
+ this.notificationChannel = notificationChannel;
74
+ this.jobQueue = new JobProcessingQueue(this.agenda);
75
+ log('creating interval to call processJobs every [%dms]', processEvery);
76
+ this.processInterval = setInterval(() => this.process(), processEvery);
77
+ this.process();
78
+ // Subscribe to job notifications for real-time processing
79
+ if (this.notificationChannel) {
80
+ log('subscribing to notification channel');
81
+ this.notificationUnsubscribe = this.notificationChannel.subscribe(this.handleNotification.bind(this));
82
+ }
83
+ }
84
+ stop() {
85
+ log.extend('stop')('stop job processor', this.isRunning);
86
+ this.isRunning = false;
87
+ if (this.processInterval) {
88
+ clearInterval(this.processInterval);
89
+ this.processInterval = undefined;
90
+ }
91
+ // Unsubscribe from notifications
92
+ if (this.notificationUnsubscribe) {
93
+ log.extend('stop')('unsubscribing from notification channel');
94
+ this.notificationUnsubscribe();
95
+ this.notificationUnsubscribe = undefined;
96
+ }
97
+ // Return both locked and running jobs so they can all be unlocked
98
+ // Running jobs are also "locked" in the database (they have lockedAt set),
99
+ // they just moved from lockedJobs to runningJobs when processing started
100
+ return [...this.lockedJobs, ...this.runningJobs];
101
+ }
102
+ /**
103
+ * Waits for all currently running jobs to finish, then stops the processor.
104
+ * Unlike stop(), this method does not immediately return - it waits for graceful completion.
105
+ * @param options - Optional timeout or AbortSignal, or timeout number directly
106
+ * @returns Promise that resolves with drain result when complete, timed out, or aborted
107
+ */
108
+ async drain(options) {
109
+ log.extend('drain')('drain called, clearing interval for processJobs()');
110
+ // Normalize options
111
+ const opts = typeof options === 'number' ? { timeout: options } : options ?? {};
112
+ // Stop accepting new jobs
113
+ if (this.processInterval) {
114
+ clearInterval(this.processInterval);
115
+ this.processInterval = undefined;
116
+ }
117
+ // Unsubscribe from notifications to stop receiving new job notifications
118
+ if (this.notificationUnsubscribe) {
119
+ log.extend('drain')('unsubscribing from notification channel');
120
+ this.notificationUnsubscribe();
121
+ this.notificationUnsubscribe = undefined;
122
+ }
123
+ const initialRunning = this.runningJobs.length;
124
+ // If no jobs are running, resolve immediately
125
+ if (initialRunning === 0) {
126
+ log.extend('drain')('no running jobs, resolving immediately');
127
+ this.isRunning = false;
128
+ return { completed: 0, running: 0, timedOut: false, aborted: false };
129
+ }
130
+ // Check if already aborted
131
+ if (opts.signal?.aborted) {
132
+ log.extend('drain')('signal already aborted, resolving immediately');
133
+ this.isRunning = false;
134
+ return { completed: 0, running: initialRunning, timedOut: false, aborted: true };
135
+ }
136
+ log.extend('drain')('waiting for %d running jobs to finish', initialRunning);
137
+ // Wait for all running jobs to complete (or timeout/abort)
138
+ return new Promise(resolve => {
139
+ let completed = 0;
140
+ let timeoutId;
141
+ const cleanup = () => {
142
+ this.agenda.off('complete', completeListener);
143
+ if (timeoutId) {
144
+ clearTimeout(timeoutId);
145
+ }
146
+ if (opts.signal) {
147
+ opts.signal.removeEventListener('abort', abortListener);
148
+ }
149
+ };
150
+ const finish = (result) => {
151
+ cleanup();
152
+ this.isRunning = false;
153
+ resolve(result);
154
+ };
155
+ const checkComplete = () => {
156
+ if (this.runningJobs.length === 0) {
157
+ log.extend('drain')('all jobs completed, resolving');
158
+ finish({ completed, running: 0, timedOut: false, aborted: false });
159
+ }
160
+ };
161
+ // Listen for 'complete' events from the agenda
162
+ const completeListener = () => {
163
+ completed++;
164
+ // Running jobs are removed after the event is emitted,
165
+ // so we check on next tick
166
+ setImmediate(checkComplete);
167
+ };
168
+ // Handle timeout
169
+ if (opts.timeout !== undefined) {
170
+ timeoutId = setTimeout(() => {
171
+ const running = this.runningJobs.length;
172
+ log.extend('drain')('timeout reached, %d jobs still running', running);
173
+ finish({ completed, running, timedOut: true, aborted: false });
174
+ }, opts.timeout);
175
+ }
176
+ // Handle abort signal
177
+ const abortListener = () => {
178
+ const running = this.runningJobs.length;
179
+ log.extend('drain')('abort signal received, %d jobs still running', running);
180
+ finish({ completed, running, timedOut: false, aborted: true });
181
+ };
182
+ if (opts.signal) {
183
+ opts.signal.addEventListener('abort', abortListener);
184
+ }
185
+ this.agenda.on('complete', completeListener);
186
+ // Also check immediately in case jobs finished between our check and listener setup
187
+ checkComplete();
188
+ });
189
+ }
190
+ /**
191
+ * Handle incoming job notification - triggers immediate processing
192
+ */
193
+ async handleNotification(notification) {
194
+ if (!this.isRunning) {
195
+ log.extend('handleNotification')('JobProcessor not running, ignoring notification');
196
+ return;
197
+ }
198
+ // Only process notifications for jobs we have definitions for
199
+ if (!this.agenda.definitions[notification.jobName]) {
200
+ log.extend('handleNotification')('no definition for job [%s], ignoring notification', notification.jobName);
201
+ return;
202
+ }
203
+ // Check if the job should run soon (within the next scan interval)
204
+ if (notification.nextRunAt && notification.nextRunAt > this.nextScanAt) {
205
+ log.extend('handleNotification')('job [%s:%s] nextRunAt is after nextScanAt, will be picked up by regular scan', notification.jobName, notification.jobId);
206
+ return;
207
+ }
208
+ log.extend('handleNotification')('received notification for job [%s:%s], triggering immediate queue fill', notification.jobName, notification.jobId);
209
+ // Fill the queue for this job type and process
210
+ await this.jobQueueFilling(notification.jobName);
211
+ this.jobProcessing();
212
+ }
213
+ // processJobs
214
+ async process() {
215
+ // Make sure an interval has actually been set
216
+ // Prevents race condition with 'Agenda.stop' and already scheduled run
217
+ if (!this.isRunning) {
218
+ log.extend('process')('JobProcessor got stopped already, returning');
219
+ return;
220
+ }
221
+ log.extend('process')('starting to process jobs');
222
+ // Go through each jobName set in 'Agenda.process' and fill the queue with the next jobs
223
+ await Promise.all(Object.keys(this.agenda.definitions).map(async (jobName) => {
224
+ log.extend('process')('queuing up job to process: [%s]', jobName);
225
+ await this.jobQueueFilling(jobName);
226
+ }));
227
+ this.jobProcessing();
228
+ }
229
+ /**
230
+ * Returns true if a job of the specified name can be locked.
231
+ * Considers maximum locked jobs at any time if self._lockLimit is > 0
232
+ * Considers maximum locked jobs of the specified name at any time if jobDefinition.lockLimit is > 0
233
+ * @param {String} name name of job to check if we should lock or not
234
+ * @returns {boolean} whether or not you should lock job
235
+ */
236
+ shouldLock(name) {
237
+ const jobDefinition = this.agenda.definitions[name];
238
+ let shouldLock = true;
239
+ // global lock limit
240
+ if (this.totalLockLimit && this.lockedJobs.length >= this.totalLockLimit) {
241
+ shouldLock = false;
242
+ }
243
+ // job specific lock limit
244
+ const status = this.jobStatus[name];
245
+ if (jobDefinition.lockLimit && status && status.locked >= jobDefinition.lockLimit) {
246
+ shouldLock = false;
247
+ }
248
+ log.extend('shouldLock')('job [%s] lock status: shouldLock = %s', name, shouldLock, `${status?.locked} >= ${jobDefinition?.lockLimit}`, `${this.lockedJobs.length} >= ${this.totalLockLimit}`);
249
+ return shouldLock;
250
+ }
251
+ /**
252
+ * Internal method that adds a job to be processed to the local queue
253
+ * @param job - Job to enqueue
254
+ */
255
+ enqueueJob(job) {
256
+ this.jobQueue.insert(job);
257
+ }
258
+ async findAndLockNextJob(jobName, definition) {
259
+ const lockDeadline = new Date(Date.now().valueOf() - definition.lockLifetime);
260
+ log.extend('findAndLockNextJob')(`looking for lockable jobs for ${jobName} (lock dead line = ${lockDeadline})`);
261
+ // Find ONE and ONLY ONE job and set the 'lockedAt' time so that job begins to be processed
262
+ const result = await this.agenda.db.getNextJobToRun(jobName, this.nextScanAt, lockDeadline, undefined, { lastModifiedBy: this.agenda.attrs.name || undefined });
263
+ if (result) {
264
+ log.extend('findAndLockNextJob')('found a job available to lock, creating a new job on Agenda with id [%s]', result._id);
265
+ return new Job(this.agenda, result, true);
266
+ }
267
+ return undefined;
268
+ }
269
+ /**
270
+ * Internal method used to fill a queue with jobs that can be run
271
+ * @param {String} name fill a queue with specific job name
272
+ * @returns {undefined}
273
+ */
274
+ async jobQueueFilling(name) {
275
+ this.isJobQueueFilling.set(name, true);
276
+ try {
277
+ // Don't lock because of a limit we have set (lockLimit, etc)
278
+ if (!this.shouldLock(name)) {
279
+ log.extend('jobQueueFilling')('lock limit reached in queue filling for [%s]', name);
280
+ return;
281
+ }
282
+ // Set the date of the next time we are going to run _processEvery function
283
+ const now = new Date();
284
+ this.nextScanAt = new Date(now.valueOf() + this.processEvery);
285
+ // For this job name, find the next job to run and lock it!
286
+ const job = await this.findAndLockNextJob(name, this.agenda.definitions[name]);
287
+ // Still have the job?
288
+ // 1. Add it to lock list
289
+ // 2. Add count of locked jobs
290
+ // 3. Queue the job to actually be run now that it is locked
291
+ // 4. Recursively run this same method we are in to check for more available jobs of same type!
292
+ if (job) {
293
+ if (job.attrs.name !== name) {
294
+ throw new Error(`got different job name: ${job.attrs.name} (actual) !== ${name} (expected)`);
295
+ }
296
+ // Before en-queing job make sure we haven't exceed our lock limits
297
+ if (!this.shouldLock(name)) {
298
+ log.extend('jobQueueFilling')('lock limit reached before job was returned. Releasing lock on [%s]', name);
299
+ this.agenda.db.unlockJob(job.attrs);
300
+ return;
301
+ }
302
+ log.extend('jobQueueFilling')('[%s:%s] job locked while filling queue', name, job.attrs._id);
303
+ this.agenda.logJobEvent({
304
+ level: 'debug',
305
+ event: 'locked',
306
+ jobId: job.attrs._id?.toString(),
307
+ jobName: name,
308
+ message: 'job locked'
309
+ });
310
+ this.updateStatus(name, 'locked', +1);
311
+ this.lockedJobs.push(job);
312
+ this.enqueueJob(job);
313
+ await this.jobQueueFilling(name);
314
+ }
315
+ else {
316
+ log.extend('jobQueueFilling')('Cannot lock job [%s]', name);
317
+ }
318
+ }
319
+ catch (error) {
320
+ log.extend('jobQueueFilling')('[%s] job lock failed while filling queue', name, error);
321
+ this.agenda.emit('error', error);
322
+ }
323
+ finally {
324
+ this.isJobQueueFilling.delete(name);
325
+ }
326
+ }
327
+ /**
328
+ * Internal method that processes any jobs in the local queue (array)
329
+ * handledJobs keeps list of already processed jobs
330
+ * @returns {undefined}
331
+ */
332
+ async jobProcessing(handledJobs = []) {
333
+ // Ensure we have jobs
334
+ if (this.jobQueue.length === 0) {
335
+ return;
336
+ }
337
+ this.localQueueProcessing += 1;
338
+ try {
339
+ const now = new Date();
340
+ // Check if there is any job that is not blocked by concurrency
341
+ const job = this.jobQueue.returnNextConcurrencyFreeJob(this.jobStatus, handledJobs);
342
+ if (!job) {
343
+ log.extend('jobProcessing')('[%s:%s] there is no job to process');
344
+ return;
345
+ }
346
+ this.jobQueue.remove(job);
347
+ if (!(await job.isExpired())) {
348
+ // check if job has expired (and therefore probably got picked up again by another queue in the meantime)
349
+ // before it even has started to run
350
+ log.extend('jobProcessing')('[%s:%s] there is a job to process (priority = %d)', job.attrs.name, job.attrs._id, job.attrs.priority, job.gotTimerToExecute);
351
+ // If the 'nextRunAt' time is older than the current time, run the job
352
+ // Otherwise, setTimeout that gets called at the time of 'nextRunAt'
353
+ if (!job.attrs.nextRunAt || job.attrs.nextRunAt <= now) {
354
+ log.extend('jobProcessing')('[%s:%s] nextRunAt is in the past, run the job immediately', job.attrs.name, job.attrs._id);
355
+ this.runOrRetry(job);
356
+ }
357
+ else {
358
+ const runIn = job.attrs.nextRunAt.getTime() - now.getTime();
359
+ if (runIn > this.processEvery) {
360
+ // this job is not in the near future, remove it (it will be picked up later)
361
+ log.extend('runOrRetry')('[%s:%s] job is too far away, freeing it up', job.attrs.name, job.attrs._id);
362
+ let lockedJobIndex = this.lockedJobs.indexOf(job);
363
+ if (lockedJobIndex === -1) {
364
+ // lookup by id
365
+ lockedJobIndex = this.lockedJobs.findIndex(j => j.attrs._id?.toString() === job.attrs._id?.toString());
366
+ }
367
+ if (lockedJobIndex === -1) {
368
+ throw new Error(`cannot find job ${job.attrs._id} in locked jobs queue?`);
369
+ }
370
+ this.lockedJobs.splice(lockedJobIndex, 1);
371
+ this.updateStatus(job.attrs.name, 'locked', -1);
372
+ }
373
+ else {
374
+ log.extend('jobProcessing')('[%s:%s] nextRunAt is in the future, calling setTimeout(%d)', job.attrs.name, job.attrs._id, runIn);
375
+ // re add to queue (puts it at the right position in the queue)
376
+ this.jobQueue.insert(job);
377
+ // ensure every job gets a timer to run at the near future time (but also ensure this time is set only once)
378
+ if (!job.gotTimerToExecute) {
379
+ job.gotTimerToExecute = true;
380
+ setTimeout(() => {
381
+ this.jobProcessing();
382
+ }, runIn > MAX_SAFE_32BIT_INTEGER ? MAX_SAFE_32BIT_INTEGER : runIn); // check if runIn is higher than unsined 32 bit int, if so, use this time to recheck,
383
+ // because setTimeout will run in an overflow otherwise and reprocesses immediately
384
+ }
385
+ }
386
+ }
387
+ }
388
+ handledJobs.push(job.attrs._id);
389
+ if (job && this.localQueueProcessing < this.maxConcurrency) {
390
+ // additionally run again and check if there are more jobs that we can process right now (as long concurrency not reached)
391
+ setImmediate(() => this.jobProcessing(handledJobs));
392
+ }
393
+ }
394
+ finally {
395
+ this.localQueueProcessing -= 1;
396
+ }
397
+ }
398
+ /**
399
+ * Internal method that tries to run a job and if it fails, retries again!
400
+ * @returns {boolean} processed a job or not
401
+ */
402
+ async runOrRetry(job) {
403
+ if (!this.isRunning) {
404
+ // const a = new Error();
405
+ // console.log('STACK', a.stack);
406
+ log.extend('runOrRetry')('JobProcessor got stopped already while calling runOrRetry, returning!');
407
+ return;
408
+ }
409
+ const jobDefinition = this.agenda.definitions[job.attrs.name];
410
+ const status = this.jobStatus[job.attrs.name];
411
+ if ((!jobDefinition.concurrency || !status || status.running < jobDefinition.concurrency) &&
412
+ this.runningJobs.length < this.maxConcurrency) {
413
+ // Add to local "running" queue
414
+ this.runningJobs.push(job);
415
+ this.updateStatus(job.attrs.name, 'running', 1);
416
+ let jobIsRunning = true;
417
+ try {
418
+ log.extend('runOrRetry')('[%s:%s] processing job', job.attrs.name, job.attrs._id);
419
+ // check if the job is still alive
420
+ const checkIfJobIsStillAlive = async () => {
421
+ // check every "this.agenda.definitions[job.attrs.name].lockLifetime / 2"" (or at mininum every processEvery)
422
+ const timeout = Math.max(this.processEvery / 2, this.agenda.definitions[job.attrs.name].lockLifetime / 2);
423
+ do {
424
+ await delay(timeout);
425
+ // when job is not running anymore, just finish
426
+ if (!jobIsRunning) {
427
+ log.extend('runOrRetry')('[%s:%s] checkIfJobIsStillAlive detected job is not running anymore. stopping check.', job.attrs.name, job.attrs._id);
428
+ return;
429
+ }
430
+ if (await job.isExpired()) {
431
+ log.extend('runOrRetry')('[%s:%s] checkIfJobIsStillAlive detected an expired job, killing it.', job.attrs.name, job.attrs._id);
432
+ this.agenda.logJobEvent({
433
+ level: 'warn',
434
+ event: 'expired',
435
+ jobId: job.attrs._id?.toString(),
436
+ jobName: job.attrs.name,
437
+ message: `job expired (lock lifetime exceeded)`
438
+ });
439
+ throw new Error(`execution of '${job.attrs.name}' canceled, execution took more than ${this.agenda.definitions[job.attrs.name].lockLifetime}ms. Call touch() for long running jobs to keep them alive.`);
440
+ }
441
+ if (!job.attrs.lockedAt) {
442
+ log.extend('runOrRetry')('[%s:%s] checkIfJobIsStillAlive detected a job without a lockedAt value, killing it.', job.attrs.name, job.attrs._id);
443
+ throw new Error(`execution of '${job.attrs.name}' canceled, no lockedAt date found. Ensure to call touch() for long running jobs to keep them alive.`);
444
+ }
445
+ } while (jobIsRunning);
446
+ };
447
+ // CALL THE ACTUAL METHOD TO PROCESS THE JOB!!!
448
+ await Promise.race([job.run(), checkIfJobIsStillAlive()]);
449
+ log.extend('runOrRetry')('[%s:%s] processing job successfull', job.attrs.name, job.attrs._id);
450
+ // Job isn't in running jobs so throw an error
451
+ if (!this.runningJobs.includes(job)) {
452
+ log.extend('runOrRetry')('[%s] callback was called, job must have been marked as complete already', job.attrs._id);
453
+ throw new Error(`callback already called - job ${job.attrs.name} already marked complete`);
454
+ }
455
+ }
456
+ catch (error) {
457
+ job.cancel(error instanceof Error ? error : undefined);
458
+ log.extend('runOrRetry')('[%s:%s] processing job failed', job.attrs.name, job.attrs._id, error);
459
+ this.agenda.logJobEvent({
460
+ level: 'error',
461
+ event: 'fail',
462
+ jobId: job.attrs._id?.toString(),
463
+ jobName: job.attrs.name,
464
+ message: `job processing error: ${error instanceof Error ? error.message : String(error)}`,
465
+ error: error instanceof Error ? error.message : String(error)
466
+ });
467
+ this.agenda.emit('error', error instanceof Error ? error : new Error(String(error)));
468
+ }
469
+ finally {
470
+ jobIsRunning = false;
471
+ // Remove the job from the running queue
472
+ let runningJobIndex = this.runningJobs.indexOf(job);
473
+ if (runningJobIndex === -1) {
474
+ // lookup by id
475
+ runningJobIndex = this.runningJobs.findIndex(j => j.attrs._id?.toString() === job.attrs._id?.toString());
476
+ }
477
+ if (runningJobIndex === -1) {
478
+ throw new Error(`cannot find job ${job.attrs._id} in running jobs queue?`);
479
+ }
480
+ this.runningJobs.splice(runningJobIndex, 1);
481
+ this.updateStatus(job.attrs.name, 'running', -1);
482
+ // Remove the job from the locked queue
483
+ let lockedJobIndex = this.lockedJobs.indexOf(job);
484
+ if (lockedJobIndex === -1) {
485
+ // lookup by id
486
+ lockedJobIndex = this.lockedJobs.findIndex(j => j.attrs._id?.toString() === job.attrs._id?.toString());
487
+ }
488
+ if (lockedJobIndex === -1) {
489
+ throw new Error(`cannot find job ${job.attrs._id} in locked jobs queue?`);
490
+ }
491
+ this.lockedJobs.splice(lockedJobIndex, 1);
492
+ this.updateStatus(job.attrs.name, 'locked', -1);
493
+ }
494
+ // Re-process jobs now that one has finished
495
+ setImmediate(() => this.jobProcessing());
496
+ return;
497
+ }
498
+ // Run the job later
499
+ log.extend('runOrRetry')('[%s:%s] concurrency preventing immediate run, pushing job to top of queue', job.attrs.name, job.attrs._id);
500
+ this.enqueueJob(job);
501
+ }
502
+ updateStatus(name, key, number) {
503
+ if (!this.jobStatus[name]) {
504
+ this.jobStatus[name] = {
505
+ locked: 0,
506
+ running: 0
507
+ };
508
+ }
509
+ this.jobStatus[name][key] += number;
510
+ }
511
+ }
512
+ //# sourceMappingURL=JobProcessor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JobProcessor.js","sourceRoot":"","sources":["../src/JobProcessor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Backend implementations have been moved to separate packages:
3
+ *
4
+ * - MongoDB: @quave/agenda-mongodb
5
+ * - PostgreSQL: @agendajs/postgres-backend
6
+ * - Redis: @agendajs/redis-backend
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { Agenda } from 'agenda';
11
+ * import { MongoBackend } from '@quave/agenda-mongodb';
12
+ *
13
+ * const agenda = new Agenda({
14
+ * backend: new MongoBackend({ address: 'mongodb://localhost/agenda' })
15
+ * });
16
+ * ```
17
+ */
18
+ export {};
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Backend implementations have been moved to separate packages:
3
+ *
4
+ * - MongoDB: @quave/agenda-mongodb
5
+ * - PostgreSQL: @agendajs/postgres-backend
6
+ * - Redis: @agendajs/redis-backend
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { Agenda } from 'agenda';
11
+ * import { MongoBackend } from '@quave/agenda-mongodb';
12
+ *
13
+ * const agenda = new Agenda({
14
+ * backend: new MongoBackend({ address: 'mongodb://localhost/agenda' })
15
+ * });
16
+ * ```
17
+ */
18
+ export {};
19
+ // No exports - backends are in separate packages
20
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/backends/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;;AAEH,iDAAiD"}