Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

427
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda