-
-
Notifications
You must be signed in to change notification settings - Fork 606
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a17d570
commit 84010f6
Showing
4 changed files
with
130 additions
and
115 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
// Simplified implementation of concurrent-queue | ||
// https://www.npmjs.com/package/concurrent-queue | ||
|
||
export function createQueue() { | ||
let concurrency = Number.POSITIVE_INFINITY; | ||
let processor; | ||
|
||
const tasks = []; | ||
let runningCount = 0; | ||
|
||
const enqueuedCallbacks = []; | ||
const processingStartedCallbacks = []; | ||
const processingEndedCallbacks = []; | ||
const drainedCallbacks = []; | ||
|
||
/** | ||
* We will trigger drained callbacks when: | ||
* tasks.length === 0 and runningCount === 0 | ||
*/ | ||
function checkDrained() { | ||
if (tasks.length === 0 && runningCount === 0) { | ||
for (const cb of drainedCallbacks) { | ||
cb(); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Attempt to start processing more tasks if we have | ||
* capacity (runningCount < concurrency). | ||
*/ | ||
function tryProcessNext() { | ||
while (tasks.length > 0 && runningCount < concurrency) { | ||
const item = tasks.shift(); | ||
runningCount++; | ||
|
||
for (const cb of processingStartedCallbacks) { | ||
cb({ item }); | ||
} | ||
|
||
const promise = Promise.resolve(processor(item)); | ||
|
||
promise | ||
.then(() => { | ||
// Fire processingEnded callbacks | ||
for (const cb of processingEndedCallbacks) { | ||
cb({ item, err: undefined }); | ||
} | ||
}) | ||
.catch(error => { | ||
// Fire processingEnded callbacks with an error | ||
for (const cb of processingEndedCallbacks) { | ||
cb({ item, err: error }); | ||
} | ||
}) | ||
.finally(() => { | ||
runningCount--; | ||
checkDrained(); | ||
tryProcessNext(); | ||
}); | ||
} | ||
} | ||
|
||
const queue = function enqueue(item) { | ||
for (const cb of enqueuedCallbacks) { | ||
cb({ item }); | ||
} | ||
tasks.push(item); | ||
|
||
tryProcessNext(); | ||
}; | ||
|
||
queue.limit = options => { | ||
if (options && typeof options.concurrency === 'number') { | ||
concurrency = options.concurrency; | ||
} | ||
return queue; | ||
}; | ||
|
||
queue.process = fn => { | ||
processor = fn; | ||
return queue; | ||
}; | ||
|
||
queue.enqueued = callback => { | ||
enqueuedCallbacks.push(callback); | ||
return queue; | ||
}; | ||
|
||
queue.processingStarted = callback => { | ||
processingStartedCallbacks.push(callback); | ||
return queue; | ||
}; | ||
|
||
queue.processingEnded = callback => { | ||
processingEndedCallbacks.push(callback); | ||
return queue; | ||
}; | ||
|
||
queue.drained = callback => { | ||
drainedCallbacks.push(callback); | ||
return queue; | ||
}; | ||
|
||
Object.defineProperty(queue, 'isDrained', { | ||
get() { | ||
return tasks.length === 0 && runningCount === 0; | ||
} | ||
}); | ||
|
||
return queue; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters