add KronSchedulerWork

This commit is contained in:
InsanusMokrassar 2021-01-02 23:56:31 +06:00
parent 3cce44664f
commit 3f132da62d
3 changed files with 95 additions and 19 deletions

View File

@ -17,7 +17,7 @@
* `KrontabTemplateWrapper` has been added
* New extension `KrontabTemplate#toKronScheduler` (works as `toSchedule`)
* **Fixed issue related to the fact that `toNearDateTime` of `CronDateTime` incorrectly handled months
* **Android target has been added**
## 0.4.2

View File

@ -0,0 +1,94 @@
package dev.inmo.krontab
import android.content.Context
import androidx.work.*
import com.soywiz.klock.DateTime
import java.util.concurrent.TimeUnit
suspend fun <T : KronSchedulerWork> Context.enqueueKronSchedulerWork(
workName: String,
delayMillis: Long,
workClass: Class<T>,
setUpRequest: suspend OneTimeWorkRequest.Builder.() -> Unit
) = WorkManager.getInstance(applicationContext).enqueueUniqueWork(
workName,
ExistingWorkPolicy.REPLACE,
OneTimeWorkRequest.Builder(workClass).apply {
setInitialDelay(delayMillis, TimeUnit.MILLISECONDS)
setUpRequest()
}.build()
)
suspend inline fun <reified T : KronSchedulerWork> Context.enqueueKronSchedulerWork(
workName: String,
delayMillis: Long,
noinline setUpRequest: suspend OneTimeWorkRequest.Builder.() -> Unit
) = enqueueKronSchedulerWork(workName, delayMillis, T::class.java, setUpRequest)
suspend fun <T : KronSchedulerWork> Context.enqueueKronSchedulerWork(
workName: String,
initialScheduler: KronScheduler,
workClass: Class<T>,
setUpRequest: suspend OneTimeWorkRequest.Builder.() -> Unit
): Operation? {
val now = DateTime.now()
val nextTriggerTime = initialScheduler.next(now)
val delayMillis = nextTriggerTime ?.minus(now) ?.millisecondsLong ?: return null
return enqueueKronSchedulerWork(workName, delayMillis, workClass, setUpRequest)
}
suspend inline fun <reified T : KronSchedulerWork> Context.enqueueKronSchedulerWork(
workName: String,
initialScheduler: KronScheduler,
noinline setUpRequest: suspend OneTimeWorkRequest.Builder.() -> Unit
) = enqueueKronSchedulerWork(workName, initialScheduler, T::class.java, setUpRequest)
/**
* Use this class as an super class in case you wish to implement krontab-based enqueuing of works
*/
abstract class KronSchedulerWork(
context: Context,
workerParams: WorkerParameters
) : CoroutineWorker(
context,
workerParams
) {
protected abstract val workName: String
protected open val prolongWork: Boolean = true
protected open val prolongOnFailure
get() = prolongWork
protected open val prolongOnException = false
protected open val prolongOnNextAbsent = false
protected abstract suspend fun kronScheduler(): KronScheduler?
protected abstract suspend fun onWork(): Result
protected open suspend fun OneTimeWorkRequest.Builder.setUpRequest() {}
protected suspend fun prolong() {
val now = DateTime.now()
val nextTriggerTime = kronScheduler() ?.let {
if (prolongOnNextAbsent) {
it.nextOrRelative(now)
} else {
it.next(now)
}
}
val delayMillis = nextTriggerTime ?.minus(now) ?.millisecondsLong ?: return
applicationContext.enqueueKronSchedulerWork(workName, delayMillis, this::class.java) { setUpRequest() }
}
override suspend fun doWork(): Result {
val result = try {
onWork()
} catch (e: Throwable) {
if (prolongOnException) {
prolong()
}
throw e
}
if (result !is Result.Failure || prolongOnFailure) {
prolong()
}
return result
}
}

View File

@ -1,18 +0,0 @@
package dev.inmo.krontab
import android.content.Context
import androidx.work.*
//fun KronScheduler.workRequest(context: Context) = OneTimeWorkRequestBuilder<>()
//
//abstract class KronSchedulerWorkRequest(
// context: Context,
// workerParams: WorkerParameters
//) : CoroutineWorker(
// context,
// workerParams
//) {
// override suspend fun doWork(): Result {
//
// }
//}