Files
amethyst/nestsClient
Vitor PamplonaandClaude Opus 5 8020102364 perf: replace synchronous OkHttp execute() with executeAsync()
Every coroutine dispatched to Dispatchers.IO is stamped BlockingContext at
dispatch time, so its worker releases its CPU permit and the shared kotlinx
scheduler grows past ncpu. A blocking execute() holds one of those threads for
the whole request; executeAsync() suspends until the response headers arrive
and releases the thread across the network round-trip.

Converts 27 call sites across quartz, commons, amethyst, nestsClient,
desktopApp and cli. executeAsync() was already the house pattern (63 existing
uses); these were the stragglers.

The withContext(Dispatchers.IO) wrappers are kept on purpose: executeAsync()
only suspends until headers, and reading the body (string()/bytes()) is still
a blocking read. Moving those onto Dispatchers.Default would hold its
core-sized CPU permits and starve the pool.

Four private helpers become suspend (decodeGifFrames, fetchFromNetwork,
downloadFirstChunk, extractFirstFrame). Each had exactly one caller, already
inside a withContext(Dispatchers.IO) in a suspend function, so nothing
propagates further.

desktopApp gains the okhttp-coroutines dependency (Apache-2.0, same version as
the okhttp it already ships).

Not converted: NipCommand.fetchText and RelayCommands.info in the CLI. amy is a
short-lived process whose main is runBlocking { dispatch(argv) } — there is no
long-lived dispatcher pool or UI thread to protect there, so blocking is by
design and making them suspend would only add risk.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 19:01:08 -04:00
..