fix(connection,adb_client): the logcat stream survives quiet windows — transport_timeout_s=None (bulk_read blocks quiet gaps; the ladder + async_stop remain recovery/cleanup), 3-line parse buffer for wrapped cmp records, public poller config accessor replaces the private reach-ins (t27 F-NEW1..3)
This commit is contained in:
1 parent
27715f6932
commit
9b3142874f
2 files changed
+79
-9
No files matched your search
@@ -216,6 +216,8 @@ class ShieldConnectionManager:
|
||||
self._logcat_failures: list[float] = []
|
||||
self._logcat_last_pkg: str | None = None
|
||||
self._logcat_last_stamp: float = -1e9
|
||||
# Injectable ladder sleep (t26: deterministic tests / future alt-floors)
|
||||
self._logcat_ladder_sleep = asyncio.sleep
|
||||
self._app_label_requests: set[str] = set()
|
||||
# Injectable clock keeps the TTL expiry tests deterministic.
|
||||
self._clock = clock
|
||||
@@ -655,22 +657,32 @@ class ShieldConnectionManager:
|
||||
)
|
||||
self._logcat_failures.clear()
|
||||
|
||||
async def _logcat_pass(self) -> None:
|
||||
"""One full consumption of the logcat line-stream (P5-3).
|
||||
|
||||
Returns when the stream ends (the dedicated connection dropped);
|
||||
errors propagate to the caller's ladder.
|
||||
"""
|
||||
async for line in self._open_logcat_stream():
|
||||
package = foreground_from_logcat([str(line)])
|
||||
if package:
|
||||
self._on_logcat_app_start(package)
|
||||
raise RuntimeError("stream ended (device closed)")
|
||||
|
||||
async def _run_logcat_stream(self) -> None:
|
||||
"""Consume the logcat line-stream; backoff-reconnect on failure.
|
||||
|
||||
The stream owns its failure ladder (separate from the ADB socket
|
||||
watchdog, reusing the same jitter): Store failures and reconnect
|
||||
with 5 s doubling to the 300 s cap ±jitter; five failures in ten
|
||||
minutes auto-disable the option for the session (heartbeat floor).
|
||||
watchdog, reusing the same jitter): Stream failures reconnect with
|
||||
5 s doubling to the 300 s cap ±jitter; five failures in ten minutes
|
||||
auto-disable the option for the session (heartbeat floor). The
|
||||
ladder sleep is injectable (_logcat_ladder_sleep) so tests stay
|
||||
deterministic.
|
||||
"""
|
||||
delay = ADB_RECONNECT_BACKOFF_START
|
||||
while not self._stopping and not self._logcat_disabled:
|
||||
try:
|
||||
async for line in self._open_logcat_stream():
|
||||
package = foreground_from_logcat([str(line)])
|
||||
if package:
|
||||
self._on_logcat_app_start(package)
|
||||
raise RuntimeError("stream ended (device closed)")
|
||||
await self._logcat_pass()
|
||||
except asyncio.CancelledError:
|
||||
raise
|
||||
except Exception as err:
|
||||
@@ -678,7 +690,7 @@ class ShieldConnectionManager:
|
||||
self._note_logcat_failure(self._clock())
|
||||
if self._stopping or self._logcat_disabled:
|
||||
break
|
||||
await asyncio.sleep(self._jitter(delay))
|
||||
await self._logcat_ladder_sleep(self._jitter(delay))
|
||||
delay = min(delay * 2, ADB_RECONNECT_BACKOFF_CAP)
|
||||
|
||||
def _ensure_logcat_stream(self) -> None:
|
||||
|
||||
Reference in new issue
Block a user