fix(typescript): honor timeoutSeconds in DockerSandboxProvider executeCode#3120
fix(typescript): honor timeoutSeconds in DockerSandboxProvider executeCode#3120jlaportebot wants to merge 1 commit into
Conversation
🤖 AI Agent: security-scanner — View details
No security issues found. |
🤖 AI Agent: breaking-change-detector — API Compatibility
API Compatibility
|
🤖 AI Agent: docs-sync-checker — Docs Sync
Docs Sync
|
🤖 AI Agent: test-generator — `agent-governance-typescript/src/sandbox.ts`
|
🤖 AI Agent: code-reviewer — View details
TL;DR: 0 blockers, 1 warning. The change improves timeout handling but introduces a potential resource cleanup issue.
Action items:
Warnings (fine as follow-up PRs):
|
|
🔴 Contributor Check: HIGH
Automated check by AGT Contributor Check. |
PR Review Summary
Verdict: AI review comments are untrusted advisory output. The summary reports workflow-generated completion status only, not model-authored pass/fail claims. |
imran-siddique
left a comment
There was a problem hiding this comment.
Legit bug fix -- timeoutSeconds was hardcoded to 60000ms regardless of session config. Clean implementation: stores config per session, passes timeout to docker exec, detects exit code 124 for killReason. Approved.
|
@MohammadHaroonAbuomar -- this PR is fully approved and all required checks are green. Could you merge it when you get a chance? Side note: my merge access stopped working -- looks like I was removed from the |
imran-siddique
left a comment
There was a problem hiding this comment.
Clean fix. The three-part timeout model is correct: (1) timeout <N> python3 inside the container enforces the wall-clock limit at the kernel level, (2) the outer execFile timeout of (timeoutSeconds + 5) * 1000 ms serves as a safety net if timeout itself hangs, and (3) exit code 124 is the GNU coreutils timeout contract for a killed child.
The killed: timedOut || killed and killReason: timedOut ? 'timeout' : killed ? 'signal' : '' correctly distinguishes between the timeout binary firing (124) vs the outer execFile wrapper killing the process for another reason. Previous code always set killReason = 'timeout' for any killed=true, which was wrong when the process was killed by signal rather than by time limit.
Storing config per session in sessionConfigs and deleting in the finally block of destroySession is correct; no leak risk.
One question worth noting for follow-up: defaultSandboxConfig().timeoutSeconds should be 60 to preserve the previous hardcoded 60_000 ms behavior. Not blocking since the test exercises the contract rather than a specific default, but worth a comment or constant.
LGTM.
imran-siddique
left a comment
There was a problem hiding this comment.
Clean fix for the missing timeout enforcement. The approach is correct:
- Storing
SandboxConfigper session and retrieving it inexecuteCodeis the right place to thread the timeout through. - Using the
timeoutcommand inside the container to enforce the wall-clock limit is better than relying solely on Node'sexecFiletimeout, which would leave the container process running. - The
execFiletimeout of(timeoutSeconds + 5) * 1000as a safety margin is sensible -- it ensures Node has a backstop if the container-level timeout somehow fails. - Exit code 124 detection is correct (
timeoutuses 124 per POSIX convention). sessionConfigs.deletein thefinallyblock prevents a memory leak.- The regression test covers the new custom timeout path.
Only the maintainer gate is failing.
…eCode - Store session config (including timeoutSeconds) in createSession - Use stored timeout in executeCode via 'timeout' command inside container - Add timeout detection (exit code 124) and proper killReason - Clean up sessionConfigs map in destroySession - Add regression test for custom timeout behavior Fixes microsoft#3118 Signed-off-by: jlaportebot <jlaportebot@gmail.com>
b0c944d to
c9020ab
Compare
|
@MohammadHaroonAbuomar can you take a look and merge when you get a chance? @imran-siddique has reviewed and approved this one. |
Summary
Fixes #3118 - The TypeScript
DockerSandboxProviderwas ignoring thetimeoutSecondsconfig parameter when executing code.Changes
timeoutSeconds) increateSession()executeCode()viatimeoutcommand inside containerkillReasonsessionConfigsmap indestroySession()Testing
All sandbox tests pass:
creates, executes, and destroys a sessionuses custom timeoutSeconds from session config(new test)The fix uses the
timeoutcommand inside the container (available inpython:3.11-slim) to properly enforce execution time limits. The Node.jsexecFiletimeout is set totimeoutSeconds + 5seconds as a safety margin.