(job: Job<Result>, options?: EnqueueOptions)
| 74 | } |
| 75 | |
| 76 | enqueue<Result>(job: Job<Result>, options?: EnqueueOptions): PromiseLike<Result> { |
| 77 | const enqueueAsyncId = executionAsyncId(); |
| 78 | const enqueuedAt = Date.now(); |
| 79 | |
| 80 | // If we're asked to enqueue a job when we're already in a async queued job context, just run it. |
| 81 | // This prevents a deadlock. |
| 82 | if (this._running.has(enqueueAsyncId)) return job(); |
| 83 | queueEnqueued.inc(); |
| 84 | return this._queue.add( |
| 85 | () => { |
| 86 | const dequeuedAt = Date.now(); |
| 87 | queueDequeued.inc(); |
| 88 | if (options?.abandonIfStale && dequeuedAt > enqueuedAt + this._staleAfterMs) { |
| 89 | queueCompleted.inc(); |
| 90 | queueStale.inc(); |
| 91 | const queueTimeSecs = (dequeuedAt - enqueuedAt) / 1000; |
| 92 | const limitSecs = this._staleAfterMs / 1000; |
| 93 | throw new Error( |
| 94 | `Compilation was in the queue too long (${queueTimeSecs.toFixed(1)}s > ${limitSecs.toFixed( |
| 95 | 1, |
| 96 | )}s)`, |
| 97 | ); |
| 98 | } |
| 99 | const jobAsyncId = executionAsyncId(); |
| 100 | if (this._running.has(jobAsyncId)) { |
| 101 | throw new Error('somehow we entered the context twice'); |
| 102 | } |
| 103 | try { |
| 104 | this._running.add(jobAsyncId); |
| 105 | const result = job(); |
| 106 | // Count completion when the job settles (even by rejection), not when it |
| 107 | // merely returns its promise. Deliberately not awaited here: a job that |
| 108 | // never settles must not hold _running (and so status().busy) forever. |
| 109 | Promise.resolve(result).then( |
| 110 | () => queueCompleted.inc(), |
| 111 | () => queueCompleted.inc(), |
| 112 | ); |
| 113 | return result; |
| 114 | } finally { |
| 115 | this._running.delete(jobAsyncId); |
| 116 | } |
| 117 | }, |
| 118 | {priority: options?.highPriority ? 100 : 0}, |
| 119 | ); |
| 120 | } |
| 121 | |
| 122 | status(): {busy: boolean; pending: number; size: number} { |
| 123 | const pending = this._queue.pending; |
no test coverage detected