fix(runtime): finalize and recover sandbox workspace exports safely (#14402)

Serialize native workspace finalization, validate streamed archives within bounded limits, and quietly recover unsafe exports from saved results. Preserve exact allocations for exhausted transient failures and provide export-only retry without rerunning the provider.

Consolidates #14314, #14315, #14329, and #14334 while preserving the already-merged finalization label changes.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip authored and GitHub committed 2026-09-28 10:57:32 -05:00
1 parent 3447609d22
commit 14795136f5
56 files changed
+3527 -143

No files matched your search

+18 -1
View File
@@ -255,6 +255,19 @@ export function postgresJsOptions(options: DatabaseClientOptions): Record<string
return driverOptions;
}
// A long advisory-lock transaction must not borrow the normal pool that its
// work needs for progress writes. Keep connection configuration private to the
// originating Db lifetime; callers receive neither URLs nor credentials.
const dedicatedDbFactories = new WeakMap<object, () => Db>();
export async function withDedicatedDbConnection<T>(db: Db, action: (dedicated: Db) => Promise<T>): Promise<T> {
const factory = dedicatedDbFactories.get(db);
if (!factory) throw new Error("dedicated_connection_requires_create_db");
const dedicated = factory();
try { return await action(dedicated); }
finally { await dedicated.$client.end({ timeout: 1 }); }
}
export function createDb(url: string, options?: DatabaseClientOptions) {
const resolved = resolveDatabaseClientOptions(options ?? databaseClientOptionsFromEnv());
const sql = postgres(url, postgresJsOptions(resolved));
@@ -263,7 +276,11 @@ export function createDb(url: string, options?: DatabaseClientOptions) {
// The registry keeps the real client (teardown must end the actual pool);
// drizzle gets the retrying face so a pooler-recycled socket replays the
// query instead of failing the request that happened to draw it.
return drizzlePg(withTransientWriteRetry(sql), { schema });
const db = drizzlePg(withTransientWriteRetry(sql), { schema });
dedicatedDbFactories.set(db, () => createDb(url, {
...resolved, maxConnections: 1, applicationName: "paperclip-workspace-finalization-lock",
}));
return db;
}
export async function getPostgresDataDirectory(url: string): Promise<string | null> {
+1
View File
@@ -1,5 +1,6 @@
export {
createDb,
withDedicatedDbConnection,
closeRegisteredClients,
getPostgresDataDirectory,
ensurePostgresDatabase,