Colas de tareas para Kotlin: Coroutines y KJobQueue
En el desarrollo moderno con Kotlin —ya sea una aplicación Android, un backend con Ktor o un microservicio— a menudo surge la necesidad de ejecutar tareas en segundo plano de forma asíncrona y en el orden correcto. Una cola de tareas (job queue) ayuda a gestionar dichas operaciones: descarga de archivos, sincronización de datos, envío de análisis, procesamiento de imágenes. En este artículo analizaremos cómo construir una cola de tareas con corrutinas de Kotlin, y también conoceremos la librería KJobQueue, una solución ligera para la gestión avanzada de tareas.
¿Por qué es necesaria una cola de tareas?
Los principales problemas que resuelve una cola de tareas son:
- Orden de ejecución — las tareas no deben competir por los recursos.
- Límite de concurrencia — por ejemplo, no más de 3 descargas simultáneas.
- Manejo de errores y reintentos — si falla, la tarea puede reiniciarse.
- Prioridades — las tareas urgentes se ejecutan primero.
- Resistencia al reinicio — la cola puede guardar su estado.
Cola simple con corrutinas (Channel)
La forma más sencilla de implementar una cola es usar Channel y una corrutina procesadora. Ejemplo:
import kotlinx.coroutines.*import kotlinx.coroutines.channels.Channel
data class Task(val id: Int, val payload: String)
suspend fun processTask(task: Task) { println("Procesando tarea ${task.id}: ${task.payload}") delay(500) // simulación de trabajo}
fun main() = runBlocking { val taskChannel = Channel<Task>(capacity = 10)
// Iniciamos el worker val worker = launch { for (task in taskChannel) { processTask(task) } }
// Agregamos tareas launch { repeat(5) { i -> taskChannel.send(Task(i, "Datos $i")) } taskChannel.close() }
worker.join()}Este enfoque es adecuado para escenarios simples, pero no admite prioridades, reintentos ni persistencia de estado.
KJobQueue — librería para colas avanzadas
KJobQueue (disponible en GitHub) es una librería ligera para Kotlin, construida sobre corrutinas. Proporciona:
- Cola con prioridades (basada en
Comparable). - Límite de concurrencia (número de tareas ejecutándose simultáneamente).
- Reintentos automáticos con retardo.
- Soporte para cancelación y detención.
- Dispatcher configurable (pool de hilos).
Instalación
Agregue en build.gradle.kts:
dependencies { implementation("io.github.kjobqueue:kjobqueue-core:1.0.0")}Ejemplo de uso de KJobQueue
import io.github.kjobqueue.*import kotlinx.coroutines.*import kotlin.random.Random
class DownloadJob(val url: String, override val priority: Int = 0) : PriorityJob { override suspend fun execute() { println("Descargando $url (prioridad $priority)") delay(1000) if (Random.nextBoolean()) throw RuntimeException("Error de red") }}
fun main() = runBlocking { val queue = JobQueue( maxConcurrent = 2, // máximo 2 tareas simultáneas retryDelayMs = 500L, // retardo antes del reintento maxRetries = 3 // máximo 3 reintentos )
queue.add(DownloadJob("https://example.com/file1", priority = 5)) queue.add(DownloadJob("https://example.com/file2", priority = 1)) queue.add(DownloadJob("https://example.com/file3", priority = 10))
delay(5000) // damos tiempo para la ejecución queue.shutdown()}Manejo de errores y reintentos
KJobQueue maneja automáticamente las excepciones. Si una tarea lanza una excepción, se