Skip to content

fix(tool-server): cap concurrent simctl device listing#480

Open
iroiro147 wants to merge 2 commits into
software-mansion:mainfrom
iroiro147:fix/simctl-list-devices-global-cap-327
Open

fix(tool-server): cap concurrent simctl device listing#480
iroiro147 wants to merge 2 commits into
software-mansion:mainfrom
iroiro147:fix/simctl-list-devices-global-cap-327

Conversation

@iroiro147

@iroiro147 iroiro147 commented Jul 8, 2026

Copy link
Copy Markdown

Summary

Fixes #327.

Adds a host-wide filesystem lock around local xcrun simctl list devices --json so multiple Argent tool-server processes do not spawn concurrent CoreSimulator discovery calls. Both listIosSimulators() and the simulator watcher now share readSimctlDevices().

The lock path also handles the two race cases found during review:

  • fresh empty/partial lock files are treated as live using filesystem mtimeMs fallback
  • stale lock cleanup is serialized through a sidecar .cleanup lock so competing stale cleaners cannot delete a fresh holder's lock

Tests

  • npm test -w @argent/tool-server -- --run test/ios-devices-runtime-kind.test.ts test/list-devices-deadline.test.ts test/simulator-watcher-init-failure.test.ts test/list-devices.test.ts
  • npm run build
  • npm run build -w @argent/tool-server
  • npm run typecheck:tests -w @argent/tool-server
  • npm run lint -- --no-warn-ignored packages/tool-server/src/utils/ios-devices.ts packages/tool-server/src/utils/simctl-config.ts packages/tool-server/src/utils/simulator-watcher.ts packages/tool-server/src/tools/devices/list-devices.ts packages/tool-server/test/ios-devices-runtime-kind.test.ts packages/tool-server/test/list-devices-deadline.test.ts packages/tool-server/test/simulator-watcher-init-failure.test.ts
  • npx prettier --check packages/tool-server/src/utils/ios-devices.ts packages/tool-server/src/utils/simctl-config.ts packages/tool-server/src/utils/simulator-watcher.ts packages/tool-server/src/tools/devices/list-devices.ts packages/tool-server/test/ios-devices-runtime-kind.test.ts packages/tool-server/test/list-devices-deadline.test.ts packages/tool-server/test/simulator-watcher-init-failure.test.ts
  • git diff --check

Note: I did not use the full @argent/tool-server Vitest suite as a local gate because this environment blocks several unrelated socket/process-list tests with listen EPERM / host-tool permission errors. The focused tool-server slice above is clean.

Signed-off-by: iroiro147 <sarthak.singh@juspay.in>

@hubgan hubgan left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for taking the time to work on this. I appreciate the contribution. There are a few areas that need some additional refinement before this is ready to merge.

Comment thread packages/tool-server/src/utils/ios-devices.ts Outdated
Comment thread packages/tool-server/src/utils/ios-devices.ts
Comment thread packages/tool-server/src/utils/ios-devices.ts
Comment thread packages/tool-server/test/ios-devices-runtime-kind.test.ts
Signed-off-by: iroiro147 <sarthak.singh@juspay.in>
@iroiro147

Copy link
Copy Markdown
Author

Thanks for the detailed review, Hubert. I pushed a follow-up commit that reworks the simctl-list lock handling around explicit ownership metadata.

What changed:

  • the main lock and cleanup sidecar now carry an owner token, pid, and createdAt
  • stale cleanup no longer removes a lock while the recorded owner process is still within the live-owner grace window
  • very old locks/cleanup sidecars can still be recovered even if the recorded pid is alive again, which covers pid reuse after a crash
  • release only unlinks when the current owner token still matches, so an old holder cannot delete a successor lock
  • listIosSimulators() no longer hides lock acquisition/wait failures as an empty simulator list, while simctl/xcrun failures still preserve the existing empty-list fallback
  • the aggregate list-devices tool catches that iOS branch failure so Android/Chromium/Vega results are still returned
  • added coverage for live-owner stale locks, pid-reuse recovery, dead-owner stale locks, orphaned cleanup sidecars, lock acquisition failures, simctl failure fallback, and aggregate list-devices degradation

Re-ran:

  • npm test -w @argent/tool-server -- --run test/ios-devices-runtime-kind.test.ts test/list-devices.test.ts test/list-devices-deadline.test.ts test/simulator-watcher-init-failure.test.ts
  • npm run typecheck:tests -w @argent/tool-server
  • npm run build -w @argent/tool-server
  • npm run lint
  • npx prettier --check packages/tool-server/src/utils/ios-devices.ts packages/tool-server/src/tools/devices/list-devices.ts packages/tool-server/test/ios-devices-runtime-kind.test.ts packages/tool-server/test/list-devices.test.ts
  • git diff --check

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

tool-server.cjs is orphaned (reparented to launchd) when the argent mcp process that spawned it exits

2 participants