mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-10-05 19:28:25 +00:00
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>