CEC-4499: add bulk update configs support (#357)

* add taskRunner util

* add bulk update config flow
This commit is contained in:
Tristan Timblin
2023-06-14 13:53:32 -04:00
committed by GitHub
parent a68c00b4ad
commit de1a5dcd2d
11 changed files with 621 additions and 7 deletions

36
src/utils/taskRunner.js Normal file
View File

@@ -0,0 +1,36 @@
export default class TaskRunner {
constructor(concurrencyLimit = 1) {
this.queue = [];
this.running = 0;
this.concurrencyLimit = concurrencyLimit;
}
execute() {
if (this.running >= this.concurrencyLimit || this.queue.length === 0) {
return;
}
const task = this.queue.shift();
this.running += 1;
task();
}
async push(fn) {
return new Promise((resolve, reject) => {
const task = async () => {
try {
const result = await fn();
resolve(result);
} catch (error) {
reject(error);
} finally {
this.running -= 1;
this.execute();
}
}
this.queue.push(task);
this.execute();
});
}
}

View File

@@ -0,0 +1,58 @@
import TaskRunner from "./taskRunner";
const mockPromise = async (id, ms) => {
await new Promise(resolve => setTimeout(resolve, ms));
return id;
}
const asyncFn1 = () => mockPromise(1, 200);
const asyncFn2 = () => mockPromise(2, 100);
const asyncFn3 = () => mockPromise(3, 50);
describe("TaskRunner", () => {
it("runs task added to queue, when space available", () => {
const taskRunner = new TaskRunner(2);
expect(taskRunner.running).toEqual(0);
taskRunner.push(() => mockPromise(1, 300));
expect(taskRunner.running).toEqual(1);
});
it("keeps task in queue when at concurrency limit", () => {
const taskRunner = new TaskRunner(2);
expect(taskRunner.running).toEqual(0);
taskRunner.push(() => mockPromise(1, 100));
taskRunner.push(() => mockPromise(2, 25));
taskRunner.push(() => mockPromise(3, 10));
expect(taskRunner.running).toEqual(2);
expect(taskRunner.queue.length).toEqual(1);
});
it("runs queued tasks as space becomes available", async () => {
const taskRunner = new TaskRunner(2);
taskRunner.push(() => mockPromise(1, 600));
taskRunner.push(() => mockPromise(2, 300));
taskRunner.push(() => mockPromise(3, 100));
expect(taskRunner.queue.length).toEqual(1);
await new Promise(r => setTimeout(r, 301));
expect(taskRunner.queue.length).toEqual(0);
});
it("runs tasks in order", async () => {
const actual = [];
const taskRunner = new TaskRunner(2);
taskRunner.push(asyncFn1)
.then((id) => {
actual.push(id);
});
taskRunner.push(asyncFn2)
.then((id) => {
actual.push(id);
});
taskRunner.push(asyncFn3)
.then((id) => {
actual.push(id);
});
await new Promise(resolve => setTimeout(resolve, 500));
expect(actual).toEqual([2, 3, 1]);
});
})