fix(FN-6035): cap scheduler dispatch by global slots
This commit is contained in:
@@ -1411,6 +1411,34 @@ describe("Scheduler", () => {
|
|||||||
expect(store.moveTask).not.toHaveBeenCalled();
|
expect(store.moveTask).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("caps in-progress dispatch by the global semaphore limit even before executors acquire slots", async () => {
|
||||||
|
vi.mocked(existsSync).mockReturnValue(true);
|
||||||
|
vi.mocked(readFile).mockResolvedValue("# Task\nDo something");
|
||||||
|
|
||||||
|
const semaphore = new AgentSemaphore(3);
|
||||||
|
const tasks = [
|
||||||
|
createMockTask({ id: "FN-001", column: "in-progress" }),
|
||||||
|
createMockTask({ id: "FN-002", column: "in-progress" }),
|
||||||
|
createMockTask({ id: "FN-003", column: "in-progress" }),
|
||||||
|
createMockTask({ id: "FN-004", column: "todo", dependencies: [] }),
|
||||||
|
createMockTask({ id: "FN-005", column: "todo", dependencies: [] }),
|
||||||
|
];
|
||||||
|
|
||||||
|
const store = createMockStore({
|
||||||
|
listTasks: vi.fn().mockResolvedValue(tasks),
|
||||||
|
getTask: vi.fn(async (taskId: string) => tasks.find((task) => task.id === taskId) ?? null),
|
||||||
|
getSettings: vi.fn().mockResolvedValue({ maxConcurrent: 5, maxWorktrees: 10 }),
|
||||||
|
updateTask: vi.fn().mockResolvedValue(undefined),
|
||||||
|
moveTask: vi.fn().mockResolvedValue(undefined),
|
||||||
|
});
|
||||||
|
|
||||||
|
const scheduler = new Scheduler(store, { semaphore });
|
||||||
|
scheduler.start();
|
||||||
|
await scheduler.schedule();
|
||||||
|
|
||||||
|
expect(store.moveTask).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
it("respects maxWorktrees limit", async () => {
|
it("respects maxWorktrees limit", async () => {
|
||||||
const tasks = [
|
const tasks = [
|
||||||
createMockTask({ id: "FN-001", column: "in-progress" }),
|
createMockTask({ id: "FN-001", column: "in-progress" }),
|
||||||
|
|||||||
@@ -1277,7 +1277,10 @@ export class Scheduler {
|
|||||||
// When a semaphore is provided, factor in its available slots so we
|
// When a semaphore is provided, factor in its available slots so we
|
||||||
// don't schedule more tasks than the global limit allows.
|
// don't schedule more tasks than the global limit allows.
|
||||||
const semaphoreAvailable = this.options.semaphore
|
const semaphoreAvailable = this.options.semaphore
|
||||||
? this.options.semaphore.availableCount
|
? Math.min(
|
||||||
|
this.options.semaphore.availableCount,
|
||||||
|
this.options.semaphore.limit - agentSlots,
|
||||||
|
)
|
||||||
: Infinity;
|
: Infinity;
|
||||||
|
|
||||||
const available = Math.min(
|
const available = Math.min(
|
||||||
|
|||||||
Reference in New Issue
Block a user