fix(coding-runtime): close Pi extension lifecycle races
This commit is contained in:
@@ -5,6 +5,7 @@ import { tmpdir } from 'node:os';
|
||||
import path from 'node:path';
|
||||
import { afterEach, describe, expect, it } from 'vitest';
|
||||
import { PiManagedExtensionHost } from '../../electron/coding-runtime/pi/extension-host';
|
||||
import { PiProjectWriteLeaseCoordinator } from '../../electron/coding-runtime/pi/write-lease';
|
||||
|
||||
const roots: string[] = [];
|
||||
const hosts: PiManagedExtensionHost[] = [];
|
||||
@@ -29,6 +30,40 @@ async function post(
|
||||
}
|
||||
|
||||
describe('managed Pi extension bridge', () => {
|
||||
it('finishes a queued HTTP request while closing a holder and waiter', async () => {
|
||||
const root = await mkdtemp(path.join(tmpdir(), 'makelore-pi-extension-close-'));
|
||||
roots.push(root);
|
||||
const leases = new PiProjectWriteLeaseCoordinator();
|
||||
const host = new PiManagedExtensionHost(leases);
|
||||
hosts.push(host);
|
||||
const holder = await host.registerWorker({
|
||||
conversationId: 'conversation-holder', generation: 1, projectId: 'project-a', extensionsDir: root,
|
||||
});
|
||||
const waiter = await host.registerWorker({
|
||||
conversationId: 'conversation-waiter', generation: 1, projectId: 'project-a', extensionsDir: root,
|
||||
});
|
||||
await Promise.all([
|
||||
host.bindRun('conversation-holder', 1, 'run-holder'),
|
||||
host.bindRun('conversation-waiter', 1, 'run-waiter'),
|
||||
]);
|
||||
const held = await post(holder, {
|
||||
action: 'lease.acquire', conversationId: 'conversation-holder', workerGeneration: 1,
|
||||
runId: 'run-holder', resourceId: 'held-tool',
|
||||
});
|
||||
expect(held.status).toBe(200);
|
||||
const waiting = post(waiter, {
|
||||
action: 'lease.acquire', conversationId: 'conversation-waiter', workerGeneration: 1,
|
||||
runId: 'run-waiter', resourceId: 'waiting-tool',
|
||||
});
|
||||
await expect.poll(() => leases.waitingCount('project-a')).toBe(1);
|
||||
|
||||
await expect(Promise.race([
|
||||
host.close().then(() => 'closed'),
|
||||
new Promise<string>((resolve) => setTimeout(() => resolve('timeout'), 500)),
|
||||
])).resolves.toBe('closed');
|
||||
await expect(waiting).resolves.toMatchObject({ status: 409 });
|
||||
});
|
||||
|
||||
it('materializes the active run into a replacement generation before spawn', async () => {
|
||||
const root = await mkdtemp(path.join(tmpdir(), 'makelore-pi-extension-rebuild-'));
|
||||
roots.push(root);
|
||||
|
||||
Reference in New Issue
Block a user