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