question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

ktor client iOS hangs forever in runBlocking

See original GitHub issue

commonMain

expect fun <T> runBlocking(context: CoroutineContext = EmptyCoroutineContext, block: suspend CoroutineScope.() -> T): T

fun getGitHub(): HttpClientCall = runBlocking {
    HttpClient().call("https://www.github.com")
}

iosMain

actual fun <T> runBlocking(context: CoroutineContext, block: suspend CoroutineScope.() -> T): T {
    return kotlinx.coroutines.runBlocking(context, block)
}

image

Xcode hangs forever when invoking the method:

func testRunBlocking() {
  GitHubKt.getGitHub()
}

If I delete HttpClient in runBlocking then the method successfully returns a value on iOS.

Versions:

kotlin_version=1.3.0-rc-190
coroutines_version=1.0.0-RC1
ktor_version=1.0.0-beta-2
serialization_version=0.8.2-rc13

Is it a known issue that ktor iOS doesn’t work in runBlocking? Is this even a ktor issue or a coroutines issue? https://github.com/Kotlin/kotlinx.coroutines/issues/462

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:20 (10 by maintainers)

github_iconTop GitHub Comments

2reactions
bootstraponlinecommented, Oct 29, 2018

I defined a custom runBlocking method using NSRunLoop and that works.

https://github.com/bootstraponline/run_blocking/commit/a7953192c7078ab41dbf382f56bdc4432a46c84b#diff-c1a933ca71f0c706f65401b240f8c806

// Expectation.kt
package example

import platform.Foundation.NSDate
import platform.Foundation.NSRunLoop
import platform.Foundation.addTimeInterval
import platform.Foundation.runUntilDate

class Expectation<T> {
    private var waiting = true
    private var result: T? = null

    fun fulfill(result: T?) {
        waiting = false
        this.result = result
    }

    fun wait(): T? {
        while (waiting) {
            advanceRunLoop()
        }

        return result
    }
}

private fun advanceRunLoop() {
    val date = NSDate().addTimeInterval(1.0) as NSDate
    NSRunLoop.mainRunLoop.runUntilDate(date)
}
// RunBlocking.kt
package example

import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Runnable
import kotlinx.coroutines.launch
import platform.Foundation.NSRunLoop
import platform.Foundation.performBlock
import kotlin.coroutines.CoroutineContext

actual fun <T> runBlocking(block: suspend () -> T): T {
    val expectation = Expectation<T>()

    GlobalScope.launch(MainRunLoopDispatcher) {
        expectation.fulfill(block.invoke())
    }

    return expectation.wait() ?: throw RuntimeException("runBlocking failed")
}

private object MainRunLoopDispatcher : CoroutineDispatcher() {
    override fun dispatch(context: CoroutineContext, block: Runnable) {
        NSRunLoop.mainRunLoop().performBlock {
            block.run()
        }
    }
}
2reactions
cy6erGn0mcommented, Oct 26, 2018

Well, running coroutines on background threads are not yet supported. Using runBlocking is quite dangerous. And for sure you can’t use runBlocking with MainLoopDispatcher and you are already on main loop. Are you sure you actually need blocking?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Ktor client unit test hangs / freezes within CoroutineScope. ...
The solution for me ended up being to run my tests within runBlocking() scope, and to inject its coroutineContext into my class to...
Read more >
WhatsNew 1.6 | Ktor Framework
OkHttp and iOS: request with only-if-cache directive in Cache-Control ... WebSocket client closes connection due to an HTTP request timeout.
Read more >
mutation attempt of frozen <object>@194c6a8 : KTOR-2947
I'm getting the same exception on iOS. Using the append function @Martynas Jegorovas uses above seems to have fixed it for me as...
Read more >
Concurrency and coroutines
Get acquainted with the main concepts for using coroutines: Asynchronous vs. parallel processing. Dispatcher for changing threads. Frozen ...
Read more >
Coroutines for Kotlin Multiplatform in Practise
Rapid Web API development with Kotlin and Ktor ... runBlocking(dispatcher) { runBlocking(dispatcher) { doWork() } } Works on iOS Deadlocks on JVM; 33....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found