Repository navigation
fix: remove an owned emulator's Metro reverses before stop kills Metro - #4105
Conversation
On Windows the adb server connects a device-opened reverse stream to the host port on its single event thread, and a refused loopback connect takes seconds. Once stop killed Metro, the app's reconnects through the reverse stalled the server and the teardown's adb devices timed out. Fixes #4101.
|
Fresh review: one actionable finding, the rest checks out. Actionable
Checked, no change needed
Non-blocking
|
|
Fresh review: one actionable finding at Actionable
Checked, no change needed
The PR stays draft without |
|
Fresh review: two actionable findings at Refusal paths: all keep the reverses now
Actionable
Checked, no change needed
The PR stays draft without |
|
Fresh review: clear at Earlier findings
Checked, no change needed
Non-blocking
|
Description
On the Windows native loop,
stim stopsometimes fails while it shuts down the owned emulator: the teardown'sadb devicestimes out after 15 s. This happened in three of the four Windows loop attempts on 10-20, and #3963 records the same signature onmainfff0bfb.The adb server is blocked, not slow.
stopkills Metro but leaves theadb reversethatandroidset up, and the debug app keeps reconnecting through it. The host server connects each device-opened stream with a blocking loopbackconnect()on its single event thread (service_to_fd). On Windows a refused connect takes about 2 s, so the retries starve every other adb client. Linux refuses at once.Controlled check with the real fixture app on the Windows runner (run 39489996200, run 39490067435):
adb devicestook 17978 ms, then 13045 ms.adb reverse --remove tcp:8082first, then the same kill:adb devicesstayed at 31-135 ms for 30 s.Other measurements
TcpClient.Connectto 127.0.0.1:8082 took 2005-2466 ms, five times in a row (run 39485502554).adb devicestake 11627 ms, against 34 ms before (run 39489996200).Solution
Right before
stopsignals Metro (the verified supervisor, or a verified dev server the supervisor left behind), and when it finds nothing listening on the port, it removes the reverses that point each owned, running emulator at the workspace's Metro port. Whenstoprefuses to signal an unverified process, Metro keeps running, so the reverses stay. After that the app's reconnects are refused on the device and never reach the host server. Ownership is checked through the emulator's own console (emu avd namemust name the recorded AVD), which does not go through the adb server. Only reverses whose host side is this workspace's Metro port are removed, including thetcp:8081fallbacklaunchAndroidAppcan add. Every call is quiet and bounded: 10 s for the console probe, 5 s for each reverse call. The removal is best effort: if it fails, the existing teardown and its failure reporting run unchanged, and the device record is kept.The Windows lane also uploads the adb server's log (
D:\e\adb.log; the server writes it to%TEMP%).Not covered: this runs only when
stopitself stops Metro for an owned emulator. When Metro dies some other way while the reverse stays (a crash,ports stop, a physical--devicephone, a non-owned emulator), the adb server on Windows can stall the same way until the app or device stops.Test plan
sim-android.test.ts: only reverses to the Metro port are listed and removed (the fallbacktcp:8081-> 8082 entry included, an unrelatedtcp:9000and alocalabstract:entry left alone), and no reverse command runs when the console names another AVD.stop.test.ts: for owned emulators in the default and a named slot, the removal runs before the supervisor or a verified leftover dev server is signalled, and when nothing listens on the port. Nothing is removed when the supervisor or the dev server it left cannot be verified, and a non-owned emulator never gets a reverse command.emu avd name,reverse --listandreverse --removeexiting ok in 29-57 ms before the supervisor phase, in both worktrees.Fixes #4101