Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: make promise throttle level consistent #240

Merged
merged 9 commits into from
Jul 5, 2023
Merged

Conversation

peternhale
Copy link
Contributor

@W-13709025@

@peternhale peternhale requested a review from mshanemc July 5, 2023 13:09
@@ -18,6 +18,15 @@ export type PromiseItem<T, O = T | undefined> = {
producer: (source: T, throttledPromise: ThrottledPromiseAll<T, O | undefined>) => Promise<O | undefined>;
};

type IndexedProducer<T, O = T> = PromiseItem<T, O> & {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Internal use type to add index to input and output.

Index is used to maintain result order to align results with Promise.all

@@ -56,7 +65,7 @@ export class ThrottledPromiseAll<T, O = T> {
* Returns the results of the promises that have been resolved.
*/
public get results(): Array<O | undefined> {
return this.#results;
return this.#results.sort((a, b) => (a?.index ?? 0) - (b?.index ?? 0)).map((r) => r?.result);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Return the results in same order supplied by user

// eslint-disable-next-line no-await-in-loop
const results = await Promise.all(
next.map((item) => item.producer(item.source, this).catch((e) => Promise.reject(e)))
const generator = function* (
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes code a bit more concise

const concurrencyPool: Array<Promise<IndexedResult<O> | undefined>> = [];
const get = generator(this.queue);
let index = 0;
while (this.queue.length > 0 || concurrencyPool.length > 0) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stay here while there are things to do.

const get = generator(this.queue);
let index = 0;
while (this.queue.length > 0 || concurrencyPool.length > 0) {
while (concurrencyPool.length < this.concurrency) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sure there are always running promises at the concurrency level

break;
}

const p: IndexedProducer<T, O> = { ...item, index: index++ };
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add in the index property to the supplied producer

concurrencyPool.push(
p
.producer(item.source, this)
.then((result) => ({ index: p.index, result }))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

capture the index in the result

}
this.#results.push(
// eslint-disable-next-line no-await-in-loop
await Promise.race([concurrencyPool.shift(), ...concurrencyPool])
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Race until one finishes.

@peternhale peternhale changed the title fix: make promising throttle level consistent fix: make promise throttle level consistent Jul 5, 2023
yield data.shift();
}
};
const concurrencyPool: Map<number, Promise<IndexedResult<O> | undefined>> = new Map<
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make pool a map, which simplifies the removal of pool entries that have resolved.

@mshanemc
Copy link
Contributor

mshanemc commented Jul 5, 2023

QA notes:

checked using plugin-dev's audit messages cmd
✅ finds extra messages
✅ finds references to non-existent messages

@@ -56,7 +65,8 @@ export class ThrottledPromiseAll<T, O = T> {
* Returns the results of the promises that have been resolved.
*/
public get results(): Array<O | undefined> {
return this.#results;
const results = this.#results;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's the point of this line? new const is just a reference to the class prop.

Maybe you want [...results].sort() if you're trying to avoid accidental mutations?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll fix it. Debug junk left over

@mshanemc mshanemc merged commit 8778166 into main Jul 5, 2023
10 checks passed
@mshanemc mshanemc deleted the phale/throttle-all-fix branch July 5, 2023 20:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants