[build-tools] Soft-stop device run sessions at time limit - #4117
Conversation
5483a8a to
dce633e
Compare
🤖 AI code reviewDecision: Ready for human review (with comments) Overall PR risk: Medium. The change modifies the shared wait loop 🟡 Warning (1)
This review is advisory — it never blocks a merge and never auto-approves. |
9492523 to
8c5da2e
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #4117 +/- ##
==========================================
+ Coverage 63.53% 63.54% +0.02%
==========================================
Files 1028 1028
Lines 47033 47054 +21
Branches 9884 9891 +7
==========================================
+ Hits 29879 29898 +19
- Misses 17053 17055 +2
Partials 101 101 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
Adds a configurable “soft stop” time limit to remote device-run session steps in @expo/build-tools, allowing sessions to end gracefully (returning normally) so cleanup and always() artifact upload steps can still run, instead of relying on hard job cancellation.
Changes:
- Add optional
max_duration_secondsstep input to agent-device, Argent, and serve-sim remote-session build functions. - Implement a combined abort signal (external cancellation + duration deadline) and clear the scheduled timeout on exit.
- Extend unit tests for
waitForDeviceRunSessionStoppedAsyncto cover duration expiry, abort behavior, and timeout cleanup.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/build-tools/src/steps/utils/remoteDeviceRunSession.ts | Adds max-duration-based abort behavior to stop polling/exit cleanly and clears the duration timeout in finally. |
| packages/build-tools/src/steps/utils/tests/remoteDeviceRunSession.test.ts | Adds timer mocking and new test cases for duration expiry and timeout cleanup. |
| packages/build-tools/src/steps/functions/startServeSimRemoteSession.ts | Adds max_duration_seconds input plumbing and forwards it to the session wait helper. |
| packages/build-tools/src/steps/functions/startArgentRemoteSession.ts | Adds max_duration_seconds input plumbing and forwards it to the session wait helper. |
| packages/build-tools/src/steps/functions/startAgentDeviceRemoteSession.ts | Adds max_duration_seconds input plumbing and forwards it to the session wait helper. |
| CHANGELOG.md | Adds a release-note entry for the soft-stop behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
8e549dd to
bc2879e
Compare
szdziedzic
left a comment
There was a problem hiding this comment.
actually one question - what would happen here if there was a queue for free tier some time in the future?
would it make sense to make request to WWW once we really start the session to ask for time until termination to always have correct value? we can set this value as time_until_termination - some_const. Does it make sense?
bc2879e to
34253b9
Compare
Nothing? Are you thinking of preempting free tier sessions prematurely? I think that's a different topic?
This sounds like "spot instances" which I think is a separate topic? Currently I would expect |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.
Suppressed comments (2)
packages/build-tools/src/steps/utils/remoteDeviceRunSession.ts:178
- This log line says the device run session will stop automatically after
maxDurationSeconds, but the duration timeout only aborts polling (it doesn’t request the session to stop). Consider rewording to reflect what actually happens (e.g., polling/this step stops waiting) to avoid confusing operational logs.
if (durationTimeout !== undefined) {
logger.info(
`The device run session will stop automatically after ${maxDurationSeconds} seconds.`
);
packages/build-tools/src/steps/utils/remoteDeviceRunSession.ts:174
- If the passed
signalis already aborted, the function still logs that the remote session is live and that it will poll, even though the polling loop is skipped. This produces misleading logs on early-abort paths; consider returning early before logging whensignal.abortedis true.
This issue also appears on line 175 of the same file.
try {
logger.info(
`Remote session is live. Polling device run session ${deviceRunSessionId} until it is stopped.`
);
|
✅ Thank you for adding the changelog entry! |
Why
Currently, simulator sessions may end at hard 2h job run time limit (and we also override job run's "max run time seconds" to denote "max device run session run time"). This is bad because when job run exceeds its run time, it gets immediately killed and the worker cannot upload screen recordings.
How
Added
max_duration_secondsparam to remote-session build functions. Added duration abort controller/signal and merged it with the cancel abort signal. Whichever happens first — cancel or abort — is going to cause waiting to stop and upload artifacts and exit cleanly.Linear: https://linear.app/expo/issue/ENG-25528/soft-stop-device-run-sessions-at-time-limit
Note: this is going to lower the max run time for device run sessions in https://github.com/expo/universe/pull/29554 cause we need to stop simulator session at 2h – (time it takes to upload stuff).
Test plan
When
max_duration_secondsis not provided we do not do anything. So, we'll deploy this, add the param and see if things are ok.