fix: dispatch Relay.connect() off the calling thread

OkHttpClient.newWebSocket() can block on its shared TaskRunner lock
for several seconds under contention. UI callbacks that invoke
RelayPool.sendToRelayOrEphemeral were calling Relay.connect() inline
on the main thread, producing 5s+ ANRs. Dispatch connect() through a
small dedicated thread pool so callers never wait on WebSocket setup.
This commit is contained in:
Barry Deen
2026-05-03 20:47:03 -04:00
parent 08d1340e9e
commit 955787eaad
@@ -50,6 +50,14 @@ class Relay(
Thread(r, "relay-reconnect").apply { isDaemon = true }
}
/** OkHttpClient.newWebSocket() can block on the shared TaskRunner lock for several
* seconds under contention — running it on the main thread causes ANRs. Dispatch
* connect() through this pool so callers (UI handlers, RelayPool.sendToRelayOrEphemeral)
* never wait on it. Sized to allow a few parallel connects without unbounded thread growth. */
private val connectExecutor = Executors.newFixedThreadPool(4) { r ->
Thread(r, "relay-connect").apply { isDaemon = true }
}
fun createClient(): OkHttpClient = HttpClientFactory.createRelayClient()
}
@@ -79,6 +87,10 @@ class Relay(
var onBytesSent: ((url: String, size: Int) -> Unit)? = null
fun connect() {
connectExecutor.execute { connectBlocking() }
}
private fun connectBlocking() {
synchronized(connectLock) {
if (isConnected || webSocket != null) return