Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/disconnect-after-run.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@e2b/desktop": patch
"@e2b/desktop-python": patch
---

Disconnect from fire-and-forget background commands. After background `commands.run` calls whose output is never read (`xdg-open`, `gtk-launch`, `Xvfb`, `startxfce4`), the SDK now calls `.disconnect()` so it stops holding the command's event stream open while the process keeps running.
19 changes: 13 additions & 6 deletions packages/js-sdk/src/sandbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -467,9 +467,10 @@ export class Sandbox extends SandboxBase {
* @param fileOrUrl - The file or URL to open.
*/
async open(fileOrUrl: string): Promise<void> {
await this.commands.run(`xdg-open ${fileOrUrl}`, {
const handle = await this.commands.run(`xdg-open ${fileOrUrl}`, {
background: true,
})
await handle.disconnect()
}

/**
Expand Down Expand Up @@ -511,10 +512,14 @@ export class Sandbox extends SandboxBase {
* @param uri - The URI to open in the application.
*/
async launch(application: string, uri?: string): Promise<void> {
await this.commands.run(`gtk-launch ${application} ${uri ?? ''}`, {
background: true,
timeoutMs: 0,
})
const handle = await this.commands.run(
`gtk-launch ${application} ${uri ?? ''}`,
{
background: true,
timeoutMs: 0,
}
)
await handle.disconnect()
}

protected async _start(display: string, opts?: SandboxOpts): Promise<void> {
Expand All @@ -523,11 +528,12 @@ export class Sandbox extends SandboxBase {
this.stream = new VNCServer(this)

const [width, height] = opts?.resolution ?? [1024, 768]
await this.commands.run(
const xvfbHandle = await this.commands.run(
`Xvfb ${display} -ac -screen 0 ${width}x${height}x24 ` +
`-retro -dpi ${opts?.dpi ?? 96} -nolisten tcp -nolisten unix`,
{ background: true, timeoutMs: 0 }
)
await xvfbHandle.disconnect()

const hasStarted = await this.waitAndVerify(
`xdpyinfo -display ${display}`,
Expand Down Expand Up @@ -559,6 +565,7 @@ export class Sandbox extends SandboxBase {
timeoutMs: 0,
})
this.lastXfce4Pid = result.pid
await result.disconnect()
}
}

Expand Down
15 changes: 9 additions & 6 deletions packages/python-sdk/e2b_desktop/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,12 +260,13 @@ def create(

sbx._display = display
width, height = resolution or (1024, 768)
sbx.commands.run(
xvfb_handle = sbx.commands.run(
f"Xvfb {display} -ac -screen 0 {width}x{height}x24"
f" -retro -dpi {dpi or 96} -nolisten tcp -nolisten unix",
background=True,
timeout=0,
)
xvfb_handle.disconnect()

if not sbx._wait_and_verify(
f"xdpyinfo -display {display}", lambda r: r.exit_code == 0
Expand Down Expand Up @@ -306,9 +307,9 @@ def _start_xfce4(self):
f"ps aux | grep {self._last_xfce4_pid} | grep -v grep | head -n 1"
).stdout.strip()
):
self._last_xfce4_pid = self.commands.run(
"startxfce4", background=True, timeout=0
).pid
xfce4_handle = self.commands.run("startxfce4", background=True, timeout=0)
self._last_xfce4_pid = xfce4_handle.pid
xfce4_handle.disconnect()

@property
def stream(self) -> _VNCServer:
Expand Down Expand Up @@ -511,7 +512,8 @@ def open(self, file_or_url: str):

:param file_or_url: The file or URL to open.
"""
self.commands.run(f"xdg-open {file_or_url}", background=True)
handle = self.commands.run(f"xdg-open {file_or_url}", background=True)
handle.disconnect()

def get_current_window_id(self) -> str:
"""
Expand Down Expand Up @@ -539,6 +541,7 @@ def launch(self, application: str, uri: Optional[str] = None):
"""
Launch an application.
"""
self.commands.run(
handle = self.commands.run(
f"gtk-launch {application} {uri or ''}", background=True, timeout=0
)
handle.disconnect()
Loading