Skip to content
This repository has been archived by the owner on Oct 14, 2023. It is now read-only.
/ kmm-job-queue Public archive

Persistable coroutine job queue for Kotlin Multiplatform projects.

License

Notifications You must be signed in to change notification settings

Liftric/kmm-job-queue

Repository files navigation

kmm-job-queue

Coroutine job scheduler for Kotlin Multiplatform projects. Run & repeat tasks. Rebuild them from disk. Fine tune execution with rules.

The library depends on kotlinx-serialization for the persistence of the jobs.

⚠️ The project is still work in progress and shouldn't be used in a production project.

Rules

  • Delay
  • Timeout
  • Retry
  • Periodic
  • Unique
  • Network

Capabilities

  • Cancellation (all, by id)
  • Start & stop scheduling
  • Restore from disk (after start)

Example

Define a Task (or DataTask<T>), customize its body and limit when it should repeat.

⚠️ Make sure the data you pass into the task is serializable.

@Serializable
data class UploadData(val id: String)

class UploadTask(data: UploadData): DataTask<UploadData>(data) {
    override suspend fun body() { /* Do something */ }
    override suspend fun onRepeat(cause: Throwable): Boolean { cause is NetworkException } // Won't retry if false
}

Create a single instance of the job queue on app start. To start enqueuing jobs run jobQueue.start().

⚠️ You have to provide the polymorphic serializer of your custom task if you want to persist it.

You can pass a custom Queue.Configuration or JsonStorage to the job queue.

val jobQueue = JobQueue(serializers = SerializersModule {
    polymorphic(Task::class) {
        subclass(UploadTask::class, UploadTask.serializer())
    }
})
jobQueue.start()

You can customize the jobs life cycle during schedule by defining rules.

val data = UploadData(id = "123456")
        
jobQueue.schedule(UploadTask(data)) {
    unique(data.id)
    retry(RetryLimit.Limited(3), delay = 30.seconds)
    persist()
}

You can subscribe to life cycle events (e.g. for logging).

jobQueue.listener.collect { event ->
    when (event) {
        is JobEvent.DidFail -> Logger.error(event.error)
        else -> Logger.info(event)
    }
}