perf: 4x faster startup — skip unnecessary driver reinstall, cache build products#3139
Open
qwertey6 wants to merge 2 commits intomobile-dev-inc:mainfrom
Open
perf: 4x faster startup — skip unnecessary driver reinstall, cache build products#3139qwertey6 wants to merge 2 commits intomobile-dev-inc:mainfrom
qwertey6 wants to merge 2 commits intomobile-dev-inc:mainfrom
Conversation
iOS simulators share the host's localhost, causing port collisions when
multiple Maestro processes target different sims simultaneously. Session
tracking was per-platform, so two processes on different devices would
interfere with each other's sessions.
Changes:
- Per-device session tracking: SessionStore keys are now
"{platform}_{deviceId}_{sessionId}" instead of "{platform}_{sessionId}"
- Add --driver-host-port CLI flag for explicit XCTest server port
- Auto-select available ports with isPortAvailable() check
- Refactor SessionStore from singleton to injectable class (DI)
- Add shouldCloseSession(platform, deviceId) for per-device shutdown
instead of global activeSessions().isEmpty()
- Add cross-process file locking to KeyValueStore (~/.maestro/sessions)
- Append PID to debug log directory to prevent parallel race
- Enable useJUnitPlatform() in maestro-cli (was missing)
- Add SessionStoreTest with 8 tests covering isolation and lifecycle
Verified: 3 iOS simulators + Android emulator running simultaneously,
all passing. Both --driver-host-port (explicit) and auto-port-selection
work correctly.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Default --reinstall-driver to false: reuse a healthy running driver instead of killing and reinstalling on every run (~40s saved on iOS) - XCTestDriverClient checks isChannelAlive() before reinstalling — if the user explicitly passes --reinstall-driver, honor it - Cache extracted iOS build products per-device in ~/.maestro/build-products/<deviceId>/ with SHA-256 hash validation: skips extraction when source matches cache, re-extracts on upgrade - Reduce XCTest status check HTTP read timeout from 100s to 3s - Remove Thread.sleep(1000) heartbeat delay hack (no longer needed with per-device session tracking) Single device: ~52s → ~10-12s. Three devices parallel: ~54s → ~18s. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This was referenced Apr 4, 2026
Open
Open
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Proposed changes
~4x faster startup time. Every
maestro testinvocation was spending ~40-45 seconds killing and reinstalling the XCTest driver, even when the exact same driver was already running and healthy. This PR makes driver reuse the default.Impact
--reinstall-driverdefault fromtruetofalseRoot cause of the slowness
reinstallDriver=truewas the default: Every run killed the XCTest runner, extracted build products from the JAR, ranxcodebuild test-without-building, and polled for ~40s until the runner responded.isChannelAlive()optimization was dead code:startXCTestRunner()checks if the runner is already alive, butrestartXCTestRunner()calleduninstall()first — killing the runner before the alive check could ever succeed.Changes
reinstallDrivertofalseacross all entry points (TestCommand, PrintHierarchyCommand, MaestroSessionManager, AndroidDriver, LocalXCTestInstaller, XCTestDriverClient)isChannelAlive()before reinstalling:restartXCTestRunner()now checks if the runner is responding before deciding to start fresh. Explicit--reinstall-driverstill forces a full reinstall.~/.maestro/build-products/<deviceId>/with SHA-256 hash of JAR source. Cache is validated on each run — skips extraction when hash matches, re-extracts automatically on Maestro upgrade or local rebuild./statusendpoint should respond instantly if healthy.Verification
--reinstall-driverTesting
Manually verified on iOS simulators and Android emulator. All existing tests pass.
Issues fixed
Closes #1096