Skip provider refresh when one is already in-flight
This commit is contained in:
@@ -251,6 +251,51 @@ describe("ProviderSnapshotManager", () => {
|
|||||||
manager.destroy();
|
manager.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("refresh during an in-flight refresh is a no-op", async () => {
|
||||||
|
const fetchModels = deferred<AgentModelDefinition[]>();
|
||||||
|
const fetchModes = deferred<AgentMode[]>();
|
||||||
|
const { registry, handles } = createRegistry([
|
||||||
|
createMockProvider({
|
||||||
|
provider: "codex",
|
||||||
|
fetchModels: async () => fetchModels.promise,
|
||||||
|
fetchModes: async () => fetchModes.promise,
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
const manager = new ProviderSnapshotManager(registry, createTestLogger());
|
||||||
|
const changes: ProviderSnapshotEntry[][] = [];
|
||||||
|
manager.on("change", (entries) => changes.push(entries));
|
||||||
|
|
||||||
|
manager.refresh("/tmp/project");
|
||||||
|
|
||||||
|
expect(manager.getSnapshot("/tmp/project")).toEqual([
|
||||||
|
{ provider: "codex", status: "loading" },
|
||||||
|
]);
|
||||||
|
|
||||||
|
manager.refresh("/tmp/project");
|
||||||
|
manager.refresh("/tmp/project");
|
||||||
|
manager.refresh("/tmp/project");
|
||||||
|
|
||||||
|
expect(changes).toHaveLength(1);
|
||||||
|
expect(handles.codex?.isAvailable).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
|
fetchModels.resolve([createModel("codex", "gpt-5.2")]);
|
||||||
|
fetchModes.resolve([createMode("auto")]);
|
||||||
|
|
||||||
|
await vi.waitFor(() => {
|
||||||
|
expect(getProviderEntry(manager.getSnapshot("/tmp/project"), "codex")).toMatchObject({
|
||||||
|
provider: "codex",
|
||||||
|
status: "ready",
|
||||||
|
models: [createModel("codex", "gpt-5.2")],
|
||||||
|
modes: [createMode("auto")],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(handles.codex?.fetchModels).toHaveBeenCalledTimes(1);
|
||||||
|
expect(handles.codex?.fetchModes).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
|
manager.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
test("multiple getSnapshot calls for same cwd do not trigger multiple warmUps", async () => {
|
test("multiple getSnapshot calls for same cwd do not trigger multiple warmUps", async () => {
|
||||||
const codexModels = deferred<AgentModelDefinition[]>();
|
const codexModels = deferred<AgentModelDefinition[]>();
|
||||||
const { registry, handles } = createRegistry([
|
const { registry, handles } = createRegistry([
|
||||||
|
|||||||
@@ -32,8 +32,7 @@ export class ProviderSnapshotManager {
|
|||||||
const cwdKey = normalizeCwdKey(cwd);
|
const cwdKey = normalizeCwdKey(cwd);
|
||||||
const entries = this.snapshots.get(cwdKey);
|
const entries = this.snapshots.get(cwdKey);
|
||||||
if (!entries) {
|
if (!entries) {
|
||||||
const loadingEntries = this.createLoadingEntries();
|
const loadingEntries = this.resetSnapshotToLoading(cwdKey);
|
||||||
this.snapshots.set(cwdKey, loadingEntries);
|
|
||||||
void this.warmUp(cwd);
|
void this.warmUp(cwd);
|
||||||
return entriesToArray(loadingEntries);
|
return entriesToArray(loadingEntries);
|
||||||
}
|
}
|
||||||
@@ -42,7 +41,11 @@ export class ProviderSnapshotManager {
|
|||||||
|
|
||||||
refresh(cwd?: string): void {
|
refresh(cwd?: string): void {
|
||||||
const cwdKey = normalizeCwdKey(cwd);
|
const cwdKey = normalizeCwdKey(cwd);
|
||||||
this.snapshots.set(cwdKey, this.createLoadingEntries());
|
if (this.warmUps.has(cwdKey)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.resetSnapshotToLoading(cwdKey);
|
||||||
|
this.emitChange(cwdKey);
|
||||||
void this.warmUp(cwd);
|
void this.warmUp(cwd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,6 +173,15 @@ export class ProviderSnapshotManager {
|
|||||||
return created;
|
return created;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private resetSnapshotToLoading(cwdKey: string): Map<AgentProvider, ProviderSnapshotEntry> {
|
||||||
|
const snapshot = this.getOrCreateSnapshot(cwdKey);
|
||||||
|
snapshot.clear();
|
||||||
|
for (const [provider, entry] of this.createLoadingEntries()) {
|
||||||
|
snapshot.set(provider, entry);
|
||||||
|
}
|
||||||
|
return snapshot;
|
||||||
|
}
|
||||||
|
|
||||||
private getProviderIds(): AgentProvider[] {
|
private getProviderIds(): AgentProvider[] {
|
||||||
return AGENT_PROVIDER_IDS.filter((provider) => this.providerRegistry[provider]);
|
return AGENT_PROVIDER_IDS.filter((provider) => this.providerRegistry[provider]);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user