Skip to content

[build-tools] Soft-stop device run sessions at time limit - #4117

Merged
sjchmiela merged 2 commits into
mainfrom
stanley/soft-stop-device-run-sessions
Aug 18, 2026
Merged

[build-tools] Soft-stop device run sessions at time limit#4117
sjchmiela merged 2 commits into
mainfrom
stanley/soft-stop-device-run-sessions

Conversation

@sjchmiela

@sjchmiela sjchmiela commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

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_seconds param 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_seconds is not provided we do not do anything. So, we'll deploy this, add the param and see if things are ok.

@sjchmiela
sjchmiela force-pushed the stanley/soft-stop-device-run-sessions branch 4 times, most recently from 5483a8a to dce633e Compare July 30, 2026 17:23
@sjchmiela sjchmiela changed the title [build-tools][eas-cli] Soft-stop device run sessions at time limit [build-tools] Soft-stop device run sessions at time limit Jul 30, 2026
@brentvatne brentvatne added the ai-review Commits pushed to PRs with this label be automatically reviewed. label Jul 30, 2026
@github-actions

github-actions Bot commented Jul 30, 2026

Copy link
Copy Markdown

🤖 AI code review

Decision: Ready for human review (with comments)

Overall PR risk: Medium. The change modifies the shared wait loop waitForDeviceRunSessionStoppedAsync used by all EAS Simulator session steps, combining the cancel signal with a new optional duration-based abort signal. The change is opt-in — omitting max_duration_seconds restores prior behavior — so the blast radius is bounded and a revert is direct. The one confirmed warning is a missing non-positive-value guard on max_duration_seconds, which could cause an immediate session stop if a caller passes 0 or a negative value; this is inconsistent with the sibling max_idle_time_minutes guard in the same function.

🟡 Warning (1)

  • max_duration_seconds has no guard against zero or negative valuespackages/build-tools/src/steps/utils/remoteDeviceRunSession.ts:169 (correctness) · id:3bc320016407
    Confidence: High — the code path and the sibling guard are both visible in the same function.
    Impact if shipped: Medium — a caller that passes 0 or a negative duration stops the session right after it starts.
    Suggested remediation: Guard the same way as maxIdleTimeMinutes: only arm the timer when maxDurationSeconds !== undefined && maxDurationSeconds > 0.

    Evidence and reasoning

    The code checks only maxDurationSeconds === undefined before it arms the timer. It does not treat 0 or a negative value as "disabled". A caller that passes max_duration_seconds: 0 gets a session that stops right after it starts.

    The sibling input maxIdleTimeMinutes in the same function guards with maxIdleTimeMinutes !== undefined && maxIdleTimeMinutes > 0. Its caller comment states: "A missing or non-positive value disables the idle timeout (opt-in feature)." The new max_duration_seconds input does not follow this same rule. Its behavior at 0 or a negative value differs from its neighbor.


This review is advisory — it never blocks a merge and never auto-approves.

@sjchmiela
sjchmiela force-pushed the stanley/soft-stop-device-run-sessions branch 2 times, most recently from 9492523 to 8c5da2e Compare July 30, 2026 20:56
@codecov

codecov Bot commented Jul 30, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.85714% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 63.54%. Comparing base (6cbddf5) to head (631068b).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
.../src/steps/functions/startServeSimRemoteSession.ts 33.34% 2 Missing ⚠️
...c/steps/functions/startAgentDeviceRemoteSession.ts 0.00% 1 Missing ⚠️
...ld-tools/src/steps/utils/remoteDeviceRunSession.ts 98.04% 1 Missing ⚠️
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.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_seconds step 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 waitForDeviceRunSessionStoppedAsync to 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.

Comment thread packages/build-tools/src/steps/utils/remoteDeviceRunSession.ts
Comment thread CHANGELOG.md
@sjchmiela
sjchmiela force-pushed the stanley/soft-stop-device-run-sessions branch 2 times, most recently from 8e549dd to bc2879e Compare July 30, 2026 21:31
@sjchmiela
sjchmiela marked this pull request as ready for review July 30, 2026 21:38
@sjchmiela
sjchmiela requested a review from szdziedzic July 30, 2026 21:38

@szdziedzic szdziedzic left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

awesome

@szdziedzic szdziedzic left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

@sjchmiela
sjchmiela force-pushed the stanley/soft-stop-device-run-sessions branch from bc2879e to 34253b9 Compare August 18, 2026 14:25
@sjchmiela

Copy link
Copy Markdown
Contributor Author

actually one question - what would happen here if there was a queue for free tier some time in the future?

Nothing? Are you thinking of preempting free tier sessions prematurely? I think that's a different topic?

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?

This sounds like "spot instances" which I think is a separate topic? Currently I would expect www to always respond with time_until_predictedFurthestEndedAt - offset which is what this achieves too?

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 signal is 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 when signal.aborted is 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.`
    );

@github-actions

Copy link
Copy Markdown

✅ Thank you for adding the changelog entry!

@sjchmiela
sjchmiela merged commit 0e85408 into main Aug 18, 2026
7 checks passed
@sjchmiela
sjchmiela deleted the stanley/soft-stop-device-run-sessions branch August 18, 2026 14:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-review Commits pushed to PRs with this label be automatically reviewed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants