summaryrefslogtreecommitdiff
path: root/app/src/main/java/org
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/org')
-rw-r--r--app/src/main/java/org/terst/feedreader/data/Net.kt27
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)
+ }
+ })
+}