diff options
Diffstat (limited to 'app/src/main/java/org/terst/feedreader/data')
| -rw-r--r-- | app/src/main/java/org/terst/feedreader/data/Net.kt | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/app/src/main/java/org/terst/feedreader/data/Net.kt b/app/src/main/java/org/terst/feedreader/data/Net.kt index d3720a0..4d0c956 100644 --- a/app/src/main/java/org/terst/feedreader/data/Net.kt +++ b/app/src/main/java/org/terst/feedreader/data/Net.kt @@ -1,8 +1,35 @@ package org.terst.feedreader.data +import kotlinx.coroutines.suspendCancellableCoroutine +import okhttp3.Call +import okhttp3.Callback import okhttp3.OkHttpClient +import okhttp3.Response +import java.io.IOException +import kotlin.coroutines.resume +import kotlin.coroutines.resumeWithException /** Shared OkHttp client -- one connection pool for the whole app. */ object Net { val client: OkHttpClient by lazy { OkHttpClient() } } + +// A plain call.execute() blocks the calling thread and knows nothing about the coroutine +// it's running inside -- if that coroutine gets cancelled (a screen torn down mid-save, a +// WorkManager-stopped fetch), the network call keeps right on running to completion +// regardless, tying up a thread/socket for work nothing is waiting on anymore. enqueue() +// registers real cancellation: cont.invokeOnCancellation { cancel() } actually aborts the +// in-flight HTTP call (closes the socket) instead of just abandoning the coroutine. +suspend fun Call.await(): Response = suspendCancellableCoroutine { cont -> + cont.invokeOnCancellation { cancel() } + enqueue(object : Callback { + override fun onResponse(call: Call, response: Response) { + cont.resume(response) + } + + override fun onFailure(call: Call, e: IOException) { + if (cont.isCancelled) return + cont.resumeWithException(e) + } + }) +} |
