feat(AsyncExecutionStack): Improve non-exclusive task management with concurrency limit controls and enhanced monitoring in AsyncExecutionStack.
This commit is contained in:
@ -26,4 +26,74 @@ tap.test('should run in parallel', async (toolsArg) => {
|
||||
}, 0);
|
||||
});
|
||||
|
||||
// Test default non-exclusive unlimited concurrency (no cap means all run together)
|
||||
tap.test('default non-exclusive unlimited concurrency', async (tools) => {
|
||||
const stack = new lik.AsyncExecutionStack();
|
||||
// default maxConcurrency should be unlimited (Infinity)
|
||||
expect(Number.isFinite(stack.getNonExclusiveMaxConcurrency())).toBe(false);
|
||||
const activeCounts: number[] = [];
|
||||
const tasks: Promise<void>[] = [];
|
||||
for (let i = 0; i < 4; i++) {
|
||||
tasks.push(
|
||||
stack.getNonExclusiveExecutionSlot(async () => {
|
||||
activeCounts.push(stack.getActiveNonExclusiveCount());
|
||||
await tools.delayFor(20);
|
||||
})
|
||||
);
|
||||
}
|
||||
await Promise.all(tasks);
|
||||
const maxActive = Math.max(...activeCounts);
|
||||
expect(maxActive).toBe(4);
|
||||
});
|
||||
// Test respecting a non-exclusive concurrency limit
|
||||
tap.test('non-exclusive respects maxConcurrency', async (tools) => {
|
||||
const stack = new lik.AsyncExecutionStack();
|
||||
stack.setNonExclusiveMaxConcurrency(2);
|
||||
const activeCounts: number[] = [];
|
||||
const tasks: Promise<void>[] = [];
|
||||
for (let i = 0; i < 5; i++) {
|
||||
tasks.push(
|
||||
stack.getNonExclusiveExecutionSlot(async () => {
|
||||
activeCounts.push(stack.getActiveNonExclusiveCount());
|
||||
await tools.delayFor(50);
|
||||
})
|
||||
);
|
||||
}
|
||||
await Promise.all(tasks);
|
||||
// never more than 2 at once
|
||||
const maxActive = Math.max(...activeCounts);
|
||||
expect(maxActive).toBeLessThanOrEqual(2);
|
||||
});
|
||||
|
||||
// Test concurrency stats (active vs pending) for non-exclusive tasks
|
||||
tap.test('non-exclusive concurrency stats reflect active and pending', async (tools) => {
|
||||
const stack = new lik.AsyncExecutionStack();
|
||||
stack.setNonExclusiveMaxConcurrency(2);
|
||||
// initially, no tasks
|
||||
expect(stack.getActiveNonExclusiveCount()).toBe(0);
|
||||
expect(stack.getPendingNonExclusiveCount()).toBe(0);
|
||||
|
||||
// enqueue three tasks
|
||||
const p1 = stack.getNonExclusiveExecutionSlot(async () => {
|
||||
await tools.delayFor(30);
|
||||
});
|
||||
const p2 = stack.getNonExclusiveExecutionSlot(async () => {
|
||||
await tools.delayFor(30);
|
||||
});
|
||||
const p3 = stack.getNonExclusiveExecutionSlot(async () => {
|
||||
await tools.delayFor(30);
|
||||
});
|
||||
|
||||
// give time for scheduling
|
||||
await tools.delayFor(10);
|
||||
// two should be running, one pending
|
||||
expect(stack.getActiveNonExclusiveCount()).toBe(2);
|
||||
expect(stack.getPendingNonExclusiveCount()).toBe(1);
|
||||
|
||||
await Promise.all([p1, p2, p3]);
|
||||
// after completion, counts reset
|
||||
expect(stack.getActiveNonExclusiveCount()).toBe(0);
|
||||
expect(stack.getPendingNonExclusiveCount()).toBe(0);
|
||||
});
|
||||
|
||||
export default tap.start();
|
||||
|
Reference in New Issue
Block a user