Skip to content

Commit f725be5

Browse files
committed
fix(boxlite): refresh handles after stop
1 parent 8a61e96 commit f725be5

3 files changed

Lines changed: 61 additions & 8 deletions

File tree

packages/boxlite/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@sandbank.dev/boxlite",
3-
"version": "0.4.1",
3+
"version": "0.4.2",
44
"description": "BoxLite bare-metal sandbox adapter for Sandbank",
55
"license": "MIT",
66
"type": "module",

packages/boxlite/src/local-client.ts

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -301,15 +301,51 @@ class Bridge:
301301
elif hasattr(box, "stop"):
302302
await box.stop()
303303
304+
async def _refresh_box_handle(self, box_id, started=None):
305+
rt = getattr(self, "_boxlite_rt", None)
306+
if rt is None:
307+
return self._boxes.get(box_id)
308+
309+
fresh = await rt.get(box_id)
310+
if fresh is None:
311+
raise RuntimeError(f"Cannot get fresh handle for box {box_id}")
312+
313+
old_sb = self._simple_boxes.get(box_id)
314+
old_box = self._boxes.get(box_id)
315+
if old_sb and hasattr(old_sb, "_box"):
316+
old_sb._box = fresh
317+
if started is not None:
318+
old_sb._started = started
319+
if old_box and hasattr(old_box, "_box"):
320+
old_box._box = fresh
321+
else:
322+
self._boxes[box_id] = fresh
323+
return fresh
324+
304325
async def stop(self, box_id):
305326
box = self._boxes.get(box_id)
306-
if box and hasattr(box, "stop"):
327+
if box is None:
328+
raise ValueError(f"Box not found: {box_id}")
329+
if hasattr(box, "stop"):
307330
await box.stop()
331+
await self._refresh_box_handle(box_id, False)
308332
309333
async def start(self, box_id):
310334
box = self._boxes.get(box_id)
311-
if box and hasattr(box, "start"):
312-
await box.start()
335+
if box is None:
336+
raise ValueError(f"Box not found: {box_id}")
337+
338+
fresh = await self._refresh_box_handle(box_id, False)
339+
if fresh and hasattr(fresh, "start"):
340+
await fresh.start()
341+
elif fresh and hasattr(fresh, "__aenter__"):
342+
await fresh.__aenter__()
343+
else:
344+
raise RuntimeError(f"Box has no start method: {box_id}")
345+
346+
old_sb = self._simple_boxes.get(box_id)
347+
if old_sb and hasattr(old_sb, "_started"):
348+
old_sb._started = True
313349
314350
def _get_box(self, box_id):
315351
box = self._boxes.get(box_id)

packages/boxlite/test/local-client.test.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
22
import { EventEmitter } from 'node:events'
33
import type { ChildProcess } from 'node:child_process'
44
import { Readable, Writable } from 'node:stream'
5+
import { readFileSync } from 'node:fs'
6+
import { join } from 'node:path'
57

68
// --- Mock child_process.spawn ---
79

@@ -83,10 +85,14 @@ vi.mock('node:child_process', () => ({
8385
spawn: (...args: unknown[]) => spawnMock(...args),
8486
}))
8587

86-
vi.mock('node:fs', () => ({
87-
writeFileSync: vi.fn(),
88-
unlinkSync: vi.fn(),
89-
}))
88+
vi.mock('node:fs', async (importOriginal) => {
89+
const actual = await importOriginal<typeof import('node:fs')>()
90+
return {
91+
...actual,
92+
writeFileSync: vi.fn(),
93+
unlinkSync: vi.fn(),
94+
}
95+
})
9096

9197
// --- Import after mocks ---
9298

@@ -586,4 +592,15 @@ describe('BoxLiteLocalClient', () => {
586592
expect(spawnCall[2].env.BOXLITE_BRIDGE_HOME).toBe('/custom/home')
587593
})
588594
})
595+
596+
describe('embedded bridge lifecycle', () => {
597+
it('refreshes the handle after stop and before start', () => {
598+
const source = readFileSync(join(import.meta.dirname, '../src/local-client.ts'), 'utf8')
599+
600+
expect(source).toContain('async def _refresh_box_handle(self, box_id, started=None):')
601+
expect(source).toContain('await self._refresh_box_handle(box_id, False)')
602+
expect(source).toContain('raise RuntimeError(f"Box has no start method: {box_id}")')
603+
expect(source).toContain('old_sb._started = True')
604+
})
605+
})
589606
})

0 commit comments

Comments
 (0)