mirror of
https://github.com/stablyai/orca.git
synced 2026-11-15 18:37:24 +00:00
fix(sandbox-control): the orphan sweep no longer stops warm-pool VMs (their record is the pool row)
This commit is contained in:
@@ -240,6 +240,10 @@ async function clearOrphan(db: D1Database, kind: string, id: string) {
|
||||
await db.prepare('DELETE FROM provider_orphans WHERE kind = ? AND provider_id = ? AND deleted_at IS NULL').bind(kind, id).run()
|
||||
}
|
||||
|
||||
async function isPooledVm(db: D1Database, providerName: string): Promise<boolean> {
|
||||
return (await db.prepare('SELECT 1 AS hit FROM sandbox_pool WHERE provider_name = ?').bind(providerName).first<{ hit: number }>()) !== null
|
||||
}
|
||||
|
||||
async function sweepOrphans(deps: LifecycleDeps, summary: HousekeepingSummary): Promise<void> {
|
||||
const now = deps.now()
|
||||
const grace = retention(deps).orphanGraceMs
|
||||
@@ -251,6 +255,11 @@ async function sweepOrphans(deps: LifecycleDeps, summary: HousekeepingSummary):
|
||||
if (box.tags.orcaEnv !== env || !box.tags.orcaSandbox) {
|
||||
continue
|
||||
}
|
||||
// A warm-pool VM has no sandboxes row until it is claimed; its record is the pool row.
|
||||
if (box.tags.orcaPool && (await isPooledVm(deps.db, box.name))) {
|
||||
await clearOrphan(deps.db, 'sandbox', box.name)
|
||||
continue
|
||||
}
|
||||
const row = await getSandboxByProviderName(deps.db, box.name)
|
||||
if (row && row.status !== 'destroyed') {
|
||||
await clearOrphan(deps.db, 'sandbox', box.name)
|
||||
|
||||
@@ -30,6 +30,30 @@ async function setup() {
|
||||
}
|
||||
|
||||
describe('orphan sweep', () => {
|
||||
it('never stops a warm-pool VM: its record is the pool row, not a sandboxes row', async () => {
|
||||
const { h, deps, sweep } = await setup()
|
||||
const name = 'orca-test-sbx_pooled'
|
||||
await h.vercel.createSandbox({
|
||||
name,
|
||||
snapshotId: GOLDEN,
|
||||
vcpus: 4,
|
||||
region: 'iad1',
|
||||
timeoutMs: 30 * 60_000,
|
||||
ports: [],
|
||||
networkPolicy: { allow: {} },
|
||||
tags: { orcaSandbox: 'sbx_pooled', orcaEnv: 'test', orcaPool: '1' },
|
||||
snapshotExpirationMs: 0
|
||||
})
|
||||
await deps.db
|
||||
.prepare(
|
||||
`INSERT INTO sandbox_pool (id, provider_name, machine_size, region, snapshot_id, status, created_at, updated_at) VALUES ('sbx_pooled', ?, 'standard', 'iad1', ?, 'ready', 1, 1)`
|
||||
)
|
||||
.bind(name, GOLDEN)
|
||||
.run()
|
||||
expect((await sweep()).orphanSandboxesSuspended).toBe(0)
|
||||
expect(h.vercel.boxes.get(name)!.status).toBe('running')
|
||||
})
|
||||
|
||||
it('suspends a provider sandbox with no live D1 row, deletes it after the grace period, leaves tracked ones alone', async () => {
|
||||
const { h, sweep } = await setup()
|
||||
const tracked = await h.call('POST', '/v1/sandboxes', create('ws-1'))
|
||||
|
||||
Reference in New Issue
Block a user