Skip to content

[Sharding] Fix Android session reuse with dynamic driver ports#3307

Open
sdfgsdfgd wants to merge 1 commit into
mobile-dev-inc:mainfrom
sdfgsdfgd:maestro-sharding-repair
Open

[Sharding] Fix Android session reuse with dynamic driver ports#3307
sdfgsdfgd wants to merge 1 commit into
mobile-dev-inc:mainfrom
sdfgsdfgd:maestro-sharding-repair

Conversation

@sdfgsdfgd

@sdfgsdfgd sdfgsdfgd commented May 21, 2026

Copy link
Copy Markdown
Contributor

Summary

Fix Android persistent-session reuse when a later process reconnects to an existing driver session whose Android driver port was chosen dynamically.

This is a follow-through on the Android sharding/session thread, not a new sharding model.


Changes

  • Persist the active session's driverHostPort in SessionStore.
  • Reuse that stored port when MaestroSessionManager reconnects to an active session for the same device.
  • Stop Android launchApp() from lazily calling open() when the current process is intentionally reusing an existing driver session.
  • Add hidden maestro start-session support so the persistent-session path from Add start session command to increase speed of tests #1902 is reachable and testable.
  • Pass --driver-host-port correctly through start-device.

Context

A few historical details matter here.

Before #3138, session identity was too broad for sharded Android runs. A shard could observe another shard's Android heartbeat and incorrectly decide it did not need to open its own driver.

The old launchApp() lazy-open fallback could sometimes mask that false reuse, but only if launchApp() was the first driver call. Calls like deviceInfo() could still fail before launchApp() had any chance to reopen the driver, which matches the failure shape in #1853.

#3138 fixed the larger session identity problem by moving session tracking to {platform, deviceId} and adding cross-process file locking. The remaining Android gap was port ownership: for sharded runs, the driver host port can be dynamic, so "there is an active session for this device" is still not enough. The reconnecting process also needs the driver port owned by that active session.


Android launchApp()

The launchApp() change follows directly from #1902: AndroidDriver.open is local to the current driver object, not proof that no driver session exists.

In a reused persistent session, open == false can simply mean this process did not start instrumentation itself. Calling open() from launchApp() in that state restarts instrumentation and defeats start-session.

This PR removes that fallback and leaves the open/reuse decision in MaestroSessionManager.


Session Store

The heartbeat still records session liveness, but it now also carries the optional Android driver port:

<lastHeartbeat>|driverHostPort:<port>

Old timestamp-only heartbeat values remain supported. They parse as active sessions with no stored driver port.

This keeps existing session liveness behavior while making the reuse decision complete: a later process can skip startup and connect its gRPC channel to the same endpoint as the already-running Android driver.


Validation

  • git diff --check
  • ./gradlew :maestro-client:compileKotlin :maestro-cli:test --tests maestro.cli.session.SessionStoreTest :maestro-cli:installDist
  • Live Android check on emulator-5554:
    • started start-session with --driver-host-port 61234
    • verified ~/.maestro/sessions recorded driverHostPort:61234
    • ran a separate maestro test process that selected another free port (51911)
    • verified the test reused the stored active session port and passed
    • verified session cleanup after stopping start-session
  • Local stress check: 10 visible API 30 Android emulators completed the intensive sharded flow successfully. Benchmark scaffolding and timing logs are intentionally not included.

@sdfgsdfgd sdfgsdfgd marked this pull request as ready for review May 21, 2026 01:20
@sdfgsdfgd sdfgsdfgd changed the title Fix Android persistent session reuse [Sharding] Fix Android session reuse with dynamic driver ports May 21, 2026
@sdfgsdfgd sdfgsdfgd force-pushed the maestro-sharding-repair branch 2 times, most recently from c144716 to e7637a0 Compare May 21, 2026 05:54
@sdfgsdfgd sdfgsdfgd force-pushed the maestro-sharding-repair branch from d25d7fc to de84a26 Compare May 21, 2026 15:28
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.

1 participant