Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

429
Visualizações
Kotlin coroutines - start another task if after some time the first one doesn't finish

I am using Kotlin coroutines to get data from the server, I am passing the deferred over to other functions. In case the server doesn't give an answer in 2000 ms I would like to retrive the object from a local Room DB (if it exists in a local database), but if I finally receive data from the server I would like to save in in a local DB for future calls. How can I acheive that? I thought about using withTimeout, but in this situation, there is no waiting for a response from the server after timeout.

override fun getDocument(): Deferred<Document> {
    return GlobalScope.async {
        withTimeoutOrNull(timeOut) {
            serverC.getDocument().await()
        } ?: dbC.getDocument().await()
    }
}

An idea I came up with:

fun getDocuments(): Deferred<Array<Document>> {
    return GlobalScope.async {
        val s = serverC.getDocuments()
        delay(2000)
        if (!s.isCompleted) {
            GlobalScope.launch {
                dbC.addDocuments(s.await())
            }
            val fromDb = dbC.getDocuments().await()
            if (fromDb != null) {
                fromDb
            } else {
                s.await()
            }
        } else {
            s.await()
        }
    }
}
over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

I recommend using the select expression from the kotlinx.coroutines library.
https://kotlinlang.org/docs/reference/coroutines/select-expression.html



fun CoroutineScope.getDocumentsRemote(): Deferred<List<Document>>
fun CoroutineScope.getDocumentsLocal(): Deferred<List<Document>>

@UseExperimental(ExperimentalCoroutinesApi::class)
fun CoroutineScope.getDocuments(): Deferred<List<Document>> = async {
    supervisorScope {
        val documents = getDocumentsRemote()
        select<List<Document>> {
            onTimeout(100) {
                documents.cancel()
                getDocumentsLocal().await()
            }
            documents.onAwait {
                it

            }
        }
    }
}

The select expression resumes either with the onAwait signal from the network or with the timeout. We return the local data in that case.

You may want to load documents in chunks as well, for that Channels may help too https://kotlinlang.org/docs/reference/coroutines/channels.html

And lastly, we use an Experimental API of kotlinx.coroutines in the example, the function onTimeout may change in the future versions of the library

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda