Improve OkHttp coroutines integration

This commit is contained in:
2025-09-13 10:06:42 +03:00
parent b9ecdb2db6
commit 30f97c5c82
2 changed files with 20 additions and 22 deletions

View File

@@ -5,32 +5,30 @@ import kotlinx.coroutines.CompletionHandler
import okhttp3.Call import okhttp3.Call
import okhttp3.Callback import okhttp3.Callback
import okhttp3.Response import okhttp3.Response
import okhttp3.internal.closeQuietly
import java.io.IOException import java.io.IOException
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException import kotlin.coroutines.resumeWithException
internal class ContinuationCallCallback( internal class ContinuationCallCallback(
private val call: Call, private val call: Call,
private val continuation: CancellableContinuation<Response>, private val continuation: CancellableContinuation<Response>,
) : Callback, CompletionHandler { ) : Callback, CompletionHandler {
override fun onResponse(call: Call, response: Response) { override fun onResponse(call: Call, response: Response) {
if (continuation.isActive) { continuation.resume(response) { _, value, _ ->
continuation.resume(response) value.closeQuietly()
} }
} }
override fun onFailure(call: Call, e: IOException) { override fun onFailure(call: Call, e: IOException) {
if (!call.isCanceled() && continuation.isActive) { continuation.resumeWithException(e)
continuation.resumeWithException(e) }
}
}
override fun invoke(cause: Throwable?) { override fun invoke(cause: Throwable?) {
runCatching { runCatching {
call.cancel() call.cancel()
}.onFailure { e -> }.onFailure { e ->
cause?.addSuppressed(e) cause?.addSuppressed(e)
} }
} }
} }

View File

@@ -10,8 +10,8 @@ import kotlin.contracts.contract
public suspend fun Call.await(): Response = suspendCancellableCoroutine { continuation -> public suspend fun Call.await(): Response = suspendCancellableCoroutine { continuation ->
val callback = ContinuationCallCallback(this, continuation) val callback = ContinuationCallCallback(this, continuation)
enqueue(callback)
continuation.invokeOnCancellation(callback) continuation.invokeOnCancellation(callback)
enqueue(callback)
} }
public val Response.mimeType: String? public val Response.mimeType: String?