Filas de Tarefas para Kotlin: Coroutines e KJobQueue
No desenvolvimento moderno com Kotlin — seja em aplicativos Android, backend com Ktor ou microsserviços — surge frequentemente a necessidade de executar tarefas em segundo plano de forma assíncrona e na ordem correta. Uma fila de tarefas (job queue) ajuda a gerenciar essas operações: download de arquivos, sincronização de dados, envio de analytics, processamento de imagens. Neste artigo, vamos explorar como construir uma fila de tarefas usando coroutines do Kotlin, além de conhecer a biblioteca KJobQueue — uma solução leve para gerenciamento avançado de tarefas.
Por que usar uma fila de tarefas?
Os principais problemas que uma fila de tarefas resolve:
- Ordem de execução — as tarefas não devem competir por recursos.
- Limitação de paralelismo — por exemplo, no máximo 3 downloads simultâneos.
- Tratamento de erros e novas tentativas — em caso de falha, a tarefa pode ser reiniciada.
- Prioridades — tarefas urgentes são executadas primeiro.
- Resiliência a reinicializações — a fila pode preservar o estado.
Fila simples com coroutines (Channel)
A maneira mais simples de implementar uma fila é usar Channel e uma coroutine de processamento. Exemplo:
import kotlinx.coroutines.*import kotlinx.coroutines.channels.Channel
data class Task(val id: Int, val payload: String)
suspend fun processTask(task: Task) { println("Processando tarefa ${task.id}: ${task.payload}") delay(500) // simulação de trabalho}
fun main() = runBlocking { val taskChannel = Channel<Task>(capacity = 10)
// Inicia o worker val worker = launch { for (task in taskChannel) { processTask(task) } }
// Adiciona tarefas launch { repeat(5) { i -> taskChannel.send(Task(i, "Dados $i")) } taskChannel.close() }
worker.join()}Essa abordagem é adequada para cenários simples, mas não suporta prioridades, repetições ou preservação de estado.
KJobQueue — biblioteca para fila avançada
KJobQueue (disponível no GitHub) é uma biblioteca leve para Kotlin, construída sobre coroutines. Ela oferece:
- Fila com prioridades (baseada em
Comparable). - Limitação de paralelismo (número de tarefas executadas simultaneamente).
- Novas tentativas automáticas com atraso.
- Suporte a cancelamento e parada.
- Dispatcher configurável (pool de threads).
Instalação
Adicione ao build.gradle.kts:
dependencies { implementation("io.github.kjobqueue:kjobqueue-core:1.0.0")}Exemplo de uso do 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("Baixando $url (prioridade $priority)") delay(1000) if (Random.nextBoolean()) throw RuntimeException("Erro de rede") }}
fun main() = runBlocking { val queue = JobQueue( maxConcurrent = 2, // máximo de 2 tarefas simultâneas retryDelayMs = 500L, // atraso antes de repetir maxRetries = 3 // máximo de 3 repetições )
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) // dá tempo para execução queue.shutdown()}Tratamento de erros e novas tentativas
O KJobQueue lida automaticamente com exceções. Se uma tarefa lançar uma exceção, ela