undefined
undefined

Reputation: 695

Suspend `withTimeout`

My app starts from executing coroutine:

model.viewModelScope.launch(Dispatchers.IO) {
            val timeout = withTimeoutOrNull(TIMEOUT) {
            //send some initialization server requests
            true   //timeout=true
    }
    if (timeout!=null){
        // app started ok
    } else {
        // app freezed on start
    }
}

The problem is one of the initialization step - obtain user consent to share his personal data(GDPR) Consent form is a modal popup that waits for user input.But the timer is ticking all this time. Therefore after gdpr user may see app starts too long error.

Is there way to suspend withTimeoutOrNull timer and resume it after some time?

Upvotes: 0

Views: 891

Answers (1)

Roman  Elizarov
Roman Elizarov

Reputation: 28648

It is not supported out of the box, but you can write your own version of withTimeoutOrNull that would support a pauseable timer. The key idea is to run your block in a separate coroutineScope { ... } and to launch a secondary helper coroutine that would cancel this scope after timeout. Now if you keep a reference to this helper cancellationJob, then you can cancel it when you need to pause your time and restart it when you need to resume timer.

That would give you essentially the same behavior that basic withTimeout has but with an added pauseability. A bit of extra code is needed to implement a withTimeoutOrNull variant. You'll need to catch your cancellation exception and replace it with null result.

A worked-out implementation can be found in this gist: https://gist.github.com/elizarov/c5b0fde43ca14efbb8bcab13ad43c6ca

Upvotes: 1

Related Questions