fix(runtime): honor provider acquisition timeout defaults (#14097)

Declare provider acquisition budgets so slow Daytona creation does not hit the host’s 30-second fallback. Bound creation and setup to one deadline and preserve scoped cleanup ownership after timeout. Legacy drivers retain their original call shape.

Validated by 238 provider/manifest tests, focused database and heartbeat regressions, root and standalone provider typecheck/build, and full CI. Local broad tests also expose recorded Mac baseline limitations. Greptile 5/5.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Devin FoleyandPaperclip authored and GitHub committed 2026-09-26 00:47:21 -07:00
1 parent 7f3c06dac4
commit ffa32373bc
9 files changed
+295 -77

No files matched your search

@@ -4685,14 +4685,20 @@ describeEmbeddedPostgres("environmentRuntimeService", () => {
expect(checks).toBe(readyAfterChecks);
});
it("extends plugin-backed sandbox lease RPC timeouts from provider config", async () => {
it.each([
{ label: "explicit provider and bridge budgets", config: { timeoutMs: 1_234, bridgeRequestTimeoutMs: 40_000 }, declared: 300_000, expected: 70_000 },
{ label: "declared acquisition default", config: {}, declared: 300_000, expected: 330_000 },
{ label: "explicit shorter provider budget", config: { timeoutMs: 5_000 }, declared: 300_000, expected: 35_000 },
{ label: "bridge budget does not shorten acquisition default", config: { bridgeRequestTimeoutMs: 40_000 }, declared: 300_000, expected: 330_000 },
{ label: "bridge extends the acquisition default", config: { bridgeRequestTimeoutMs: 400_000 }, declared: 300_000, expected: 430_000 },
{ label: "undeclared provider retains worker default", config: {}, declared: undefined, expected: undefined },
])("uses $label for plugin-backed sandbox acquisition", async ({ config, declared, expected }) => {
const pluginId = randomUUID();
const { companyId, environment: baseEnvironment, runId } = await seedEnvironment();
const providerConfig = {
provider: "fake-plugin",
image: "fake:test",
timeoutMs: 1_234,
bridgeRequestTimeoutMs: 40_000,
...config,
reuseLease: false,
};
const environment = {
@@ -4728,7 +4734,10 @@ describeEmbeddedPostgres("environmentRuntimeService", () => {
driverKey: "fake-plugin",
kind: "sandbox_provider",
displayName: "Fake Plugin",
configSchema: { type: "object" },
defaultAcquireTimeoutMs: declared,
// A timeoutMs schema default can mean lease lifetime (for example
// E2B). Only the dedicated declaration sets the host RPC budget.
configSchema: { type: "object", properties: { timeoutMs: { type: "number", default: 3_600_000 } } },
},
],
},
@@ -4746,8 +4755,7 @@ describeEmbeddedPostgres("environmentRuntimeService", () => {
metadata: {
provider: "fake-plugin",
image: "fake:test",
timeoutMs: 1_234,
bridgeRequestTimeoutMs: 40_000,
...config,
reuseLease: false,
},
};
@@ -4774,12 +4782,11 @@ describeEmbeddedPostgres("environmentRuntimeService", () => {
driverKey: "fake-plugin",
config: {
image: "fake:test",
timeoutMs: 1_234,
bridgeRequestTimeoutMs: 40_000,
...config,
reuseLease: false,
},
}),
70_000,
expected,
);
});
@@ -7068,7 +7075,7 @@ describeEmbeddedPostgres("environmentRuntimeService", () => {
}));
});
it("delegates plugin environment leases through the plugin worker manager", async () => {
it.each([undefined, 300_000])("delegates plugin environment leases with acquisition budget %s", async (defaultAcquireTimeoutMs) => {
const pluginId = randomUUID();
const expiresAt = new Date(Date.now() + 60_000).toISOString();
const workerManager = {
@@ -7129,6 +7136,7 @@ describeEmbeddedPostgres("environmentRuntimeService", () => {
{
driverKey: "fake-plugin",
displayName: "Fake plugin",
defaultAcquireTimeoutMs,
configSchema: { type: "object" },
},
],
@@ -7158,7 +7166,7 @@ describeEmbeddedPostgres("environmentRuntimeService", () => {
adapterType: undefined,
runId,
workspaceMode: undefined,
});
}, ...(defaultAcquireTimeoutMs === undefined ? [] : [330_000]));
expect(acquired.lease.providerLeaseId).toBe("plugin-lease-1");
expect(acquired.lease.expiresAt?.toISOString()).toBe(expiresAt);
expect(acquired.lease.metadata).toMatchObject({
+21 -6
View File
@@ -485,9 +485,16 @@ export interface EnvironmentDriverReleaseInput {
status: Extract<EnvironmentLeaseStatus, "released" | "expired" | "failed">;
}
function resolvePluginSandboxRpcTimeoutMs(config: Record<string, unknown>): number | undefined {
function resolvePluginSandboxRpcTimeoutMs(
config: Record<string, unknown>,
defaultTimeoutMs?: number,
): number | undefined {
const configuredTimeoutMs = typeof config.timeoutMs === "number" &&
Number.isFinite(config.timeoutMs) && config.timeoutMs > 0
? config.timeoutMs
: defaultTimeoutMs;
const timeoutCandidates = [
typeof config.timeoutMs === "number" ? config.timeoutMs : undefined,
configuredTimeoutMs,
typeof config.bridgeRequestTimeoutMs === "number" ? config.bridgeRequestTimeoutMs : undefined,
]
.filter((value): value is number => typeof value === "number" && Number.isFinite(value) && value > 0)
@@ -2084,7 +2091,10 @@ function createSandboxEnvironmentDriver(
? { requestedExpiresAt: requestedExpiresAtParam(input.requestedExpiresAt) }
: {}),
},
resolvePluginSandboxRpcTimeoutMs(workerConfig),
resolvePluginSandboxRpcTimeoutMs(
workerConfig,
pluginProvider.resolved.driver.defaultAcquireTimeoutMs,
),
);
} catch (error) {
const cleanup = readEnvironmentCreationCleanupError(error);
@@ -3390,7 +3400,7 @@ function createPluginEnvironmentDriver(
if (!workerManager.isRunning(plugin.id)) {
throw new Error(`Plugin environment driver "${pluginDriverProviderKey(config)}" has no running worker.`);
}
return { plugin };
return { plugin, driver };
}
async function resolvePluginDriverForRelease(input: EnvironmentDriverReleaseInput) {
@@ -3459,7 +3469,12 @@ function createPluginEnvironmentDriver(
if (parsed.driver !== "plugin") {
throw new Error(`Expected plugin environment config for driver "${input.environment.driver}".`);
}
const { plugin } = await resolvePluginDriver(parsed.config);
const { plugin, driver } = await resolvePluginDriver(parsed.config);
const rpcTimeoutMs = resolvePluginSandboxRpcTimeoutMs(
parsed.config.driverConfig,
driver.defaultAcquireTimeoutMs,
);
const timeoutOverride: [number?] = rpcTimeoutMs === undefined ? [] : [rpcTimeoutMs];
const providerLease = await workerManager.call(plugin.id, "environmentAcquireLease", {
driverKey: parsed.config.driverKey,
companyId: input.companyId,
@@ -3477,7 +3492,7 @@ function createPluginEnvironmentDriver(
...(requestedExpiresAtParam(input.requestedExpiresAt) !== undefined
? { requestedExpiresAt: requestedExpiresAtParam(input.requestedExpiresAt) }
: {}),
} as PluginEnvironmentAcquireLeaseParams);
} as PluginEnvironmentAcquireLeaseParams, ...timeoutOverride);
return await environmentsSvc.acquireLease({
companyId: input.companyId,