diff --git a/packages/js-sdk/src/sandbox/commands/commandHandle.ts b/packages/js-sdk/src/sandbox/commands/commandHandle.ts index 67852a900c..c7175cac44 100644 --- a/packages/js-sdk/src/sandbox/commands/commandHandle.ts +++ b/packages/js-sdk/src/sandbox/commands/commandHandle.ts @@ -84,8 +84,10 @@ export class CommandHandle Omit, Partial> { - private _stdout = '' - private _stderr = '' + private _stdoutChunks: string[] = [] + private _stderrChunks: string[] = [] + private _stdoutCached?: string + private _stderrCached?: string private result?: CommandResult private iterationError?: Error @@ -130,14 +132,20 @@ export class CommandHandle * Command execution stderr output. */ get stderr() { - return this._stderr + if (this._stderrCached === undefined) { + this._stderrCached = this._stderrChunks.join('') + } + return this._stderrCached } /** * Command execution stdout output. */ get stdout() { - return this._stdout + if (this._stdoutCached === undefined) { + this._stdoutCached = this._stdoutChunks.join('') + } + return this._stdoutCached } /** @@ -196,12 +204,14 @@ export class CommandHandle switch (e.value.output.case) { case 'stdout': out = new TextDecoder().decode(e.value.output.value) - this._stdout += out + this._stdoutChunks.push(out) + this._stdoutCached = undefined yield [out as Stdout, null, null] break case 'stderr': out = new TextDecoder().decode(e.value.output.value) - this._stderr += out + this._stderrChunks.push(out) + this._stderrCached = undefined yield [null, out as Stderr, null] break case 'pty': diff --git a/packages/python-sdk/e2b/sandbox_async/commands/command_handle.py b/packages/python-sdk/e2b/sandbox_async/commands/command_handle.py index dfe34e8383..fe63ef0f9c 100644 --- a/packages/python-sdk/e2b/sandbox_async/commands/command_handle.py +++ b/packages/python-sdk/e2b/sandbox_async/commands/command_handle.py @@ -41,14 +41,18 @@ def stdout(self): """ Command stdout output. """ - return self._stdout + if self._stdout_cached is None: + self._stdout_cached = "".join(self._stdout_chunks) + return self._stdout_cached @property def stderr(self): """ Command stderr output. """ - return self._stderr + if self._stderr_cached is None: + self._stderr_cached = "".join(self._stderr_chunks) + return self._stderr_cached @property def error(self): @@ -87,8 +91,10 @@ def __init__( self._handle_kill = handle_kill self._events = events - self._stdout: str = "" - self._stderr: str = "" + self._stdout_chunks: list[str] = [] + self._stderr_chunks: list[str] = [] + self._stdout_cached: Optional[str] = None + self._stderr_cached: Optional[str] = None self._on_stdout = on_stdout self._on_stderr = on_stderr @@ -113,18 +119,20 @@ async def _iterate_events( if event.event.HasField("data"): if event.event.data.stdout: out = event.event.data.stdout.decode("utf-8", "replace") - self._stdout += out + self._stdout_chunks.append(out) + self._stdout_cached = None yield out, None, None if event.event.data.stderr: out = event.event.data.stderr.decode("utf-8", "replace") - self._stderr += out + self._stderr_chunks.append(out) + self._stderr_cached = None yield None, out, None if event.event.data.pty: yield None, None, event.event.data.pty if event.event.HasField("end"): self._result = CommandResult( - stdout=self._stdout, - stderr=self._stderr, + stdout="".join(self._stdout_chunks), + stderr="".join(self._stderr_chunks), exit_code=event.event.end.exit_code, error=event.event.end.error, ) @@ -176,8 +184,8 @@ async def wait(self) -> CommandResult: if self._result.exit_code != 0: raise CommandExitException( - stdout=self._stdout, - stderr=self._stderr, + stdout=self._result.stdout, + stderr=self._result.stderr, exit_code=self._result.exit_code, error=self._result.error, ) diff --git a/packages/python-sdk/e2b/sandbox_sync/commands/command_handle.py b/packages/python-sdk/e2b/sandbox_sync/commands/command_handle.py index a58a613e02..b2416d2eee 100644 --- a/packages/python-sdk/e2b/sandbox_sync/commands/command_handle.py +++ b/packages/python-sdk/e2b/sandbox_sync/commands/command_handle.py @@ -37,8 +37,8 @@ def __init__( self._handle_kill = handle_kill self._events = events - self._stdout: str = "" - self._stderr: str = "" + self._stdout_chunks: list[str] = [] + self._stderr_chunks: list[str] = [] self._result: Optional[CommandResult] = None self._iteration_exception: Optional[Exception] = None @@ -67,18 +67,18 @@ def _handle_events( if event.event.HasField("data"): if event.event.data.stdout: out = event.event.data.stdout.decode("utf-8", "replace") - self._stdout += out + self._stdout_chunks.append(out) yield out, None, None if event.event.data.stderr: out = event.event.data.stderr.decode("utf-8", "replace") - self._stderr += out + self._stderr_chunks.append(out) yield None, out, None if event.event.data.pty: yield None, None, event.event.data.pty if event.event.HasField("end"): self._result = CommandResult( - stdout=self._stdout, - stderr=self._stderr, + stdout="".join(self._stdout_chunks), + stderr="".join(self._stderr_chunks), exit_code=event.event.end.exit_code, error=event.event.end.error, ) @@ -131,8 +131,8 @@ def wait( if self._result.exit_code != 0: raise CommandExitException( - stdout=self._stdout, - stderr=self._stderr, + stdout=self._result.stdout, + stderr=self._result.stderr, exit_code=self._result.exit_code, error=self._result.error, )