mirror of
https://github.com/InsanusMokrassar/krontab.git
synced 2024-11-23 02:28:52 +00:00
fixed issues
This commit is contained in:
parent
3f132da62d
commit
e04d14ccb1
@ -5,45 +5,68 @@ import androidx.work.*
|
|||||||
import com.soywiz.klock.DateTime
|
import com.soywiz.klock.DateTime
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will enqueue [OneTimeWorkRequest] with [workName] and [existingWorkPolicy]. Use [setUpRequest] callback
|
||||||
|
* in case you need some additional actions to do before request will be enqueued
|
||||||
|
*/
|
||||||
suspend fun <T : KronSchedulerWork> Context.enqueueKronSchedulerWork(
|
suspend fun <T : KronSchedulerWork> Context.enqueueKronSchedulerWork(
|
||||||
workName: String,
|
workName: String,
|
||||||
delayMillis: Long,
|
delayMillis: Long,
|
||||||
workClass: Class<T>,
|
workClass: Class<T>,
|
||||||
setUpRequest: suspend OneTimeWorkRequest.Builder.() -> Unit
|
existingWorkPolicy: ExistingWorkPolicy = ExistingWorkPolicy.REPLACE,
|
||||||
|
setUpRequest: suspend OneTimeWorkRequest.Builder.() -> Unit = {}
|
||||||
) = WorkManager.getInstance(applicationContext).enqueueUniqueWork(
|
) = WorkManager.getInstance(applicationContext).enqueueUniqueWork(
|
||||||
workName,
|
workName,
|
||||||
ExistingWorkPolicy.REPLACE,
|
existingWorkPolicy,
|
||||||
OneTimeWorkRequest.Builder(workClass).apply {
|
OneTimeWorkRequest.Builder(workClass).apply {
|
||||||
setInitialDelay(delayMillis, TimeUnit.MILLISECONDS)
|
setInitialDelay(delayMillis, TimeUnit.MILLISECONDS)
|
||||||
setUpRequest()
|
setUpRequest()
|
||||||
}.build()
|
}.build()
|
||||||
)
|
)
|
||||||
|
/**
|
||||||
|
* This method is shortcut for [enqueueKronSchedulerWork] with reified [T] parameter
|
||||||
|
*/
|
||||||
suspend inline fun <reified T : KronSchedulerWork> Context.enqueueKronSchedulerWork(
|
suspend inline fun <reified T : KronSchedulerWork> Context.enqueueKronSchedulerWork(
|
||||||
workName: String,
|
workName: String,
|
||||||
delayMillis: Long,
|
delayMillis: Long,
|
||||||
noinline setUpRequest: suspend OneTimeWorkRequest.Builder.() -> Unit
|
existingWorkPolicy: ExistingWorkPolicy = ExistingWorkPolicy.REPLACE,
|
||||||
) = enqueueKronSchedulerWork(workName, delayMillis, T::class.java, setUpRequest)
|
noinline setUpRequest: suspend OneTimeWorkRequest.Builder.() -> Unit = {}
|
||||||
|
) = enqueueKronSchedulerWork(workName, delayMillis, T::class.java, existingWorkPolicy, setUpRequest)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is shortcut for [enqueueKronSchedulerWork] with [initialScheduler]. It will try to calculate delay by
|
||||||
|
* itself. In case if [KronScheduler.next] of [initialScheduler] will return null, work WILL NOT be enqueued
|
||||||
|
*
|
||||||
|
* @return null in case if [KronScheduler.next] of [initialScheduler] has returned null and work has not been enqueued
|
||||||
|
*/
|
||||||
suspend fun <T : KronSchedulerWork> Context.enqueueKronSchedulerWork(
|
suspend fun <T : KronSchedulerWork> Context.enqueueKronSchedulerWork(
|
||||||
workName: String,
|
workName: String,
|
||||||
initialScheduler: KronScheduler,
|
initialScheduler: KronScheduler,
|
||||||
workClass: Class<T>,
|
workClass: Class<T>,
|
||||||
setUpRequest: suspend OneTimeWorkRequest.Builder.() -> Unit
|
existingWorkPolicy: ExistingWorkPolicy = ExistingWorkPolicy.REPLACE,
|
||||||
|
setUpRequest: suspend OneTimeWorkRequest.Builder.() -> Unit = {}
|
||||||
): Operation? {
|
): Operation? {
|
||||||
val now = DateTime.now()
|
val now = DateTime.now()
|
||||||
val nextTriggerTime = initialScheduler.next(now)
|
val nextTriggerTime = initialScheduler.next(now)
|
||||||
val delayMillis = nextTriggerTime ?.minus(now) ?.millisecondsLong ?: return null
|
val delayMillis = nextTriggerTime ?.minus(now) ?.millisecondsLong ?: return null
|
||||||
|
|
||||||
return enqueueKronSchedulerWork(workName, delayMillis, workClass, setUpRequest)
|
return enqueueKronSchedulerWork(workName, delayMillis, workClass, existingWorkPolicy, setUpRequest)
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* This method is shortcut for [enqueueKronSchedulerWork] with reified [T]
|
||||||
|
*/
|
||||||
suspend inline fun <reified T : KronSchedulerWork> Context.enqueueKronSchedulerWork(
|
suspend inline fun <reified T : KronSchedulerWork> Context.enqueueKronSchedulerWork(
|
||||||
workName: String,
|
workName: String,
|
||||||
initialScheduler: KronScheduler,
|
initialScheduler: KronScheduler,
|
||||||
noinline setUpRequest: suspend OneTimeWorkRequest.Builder.() -> Unit
|
existingWorkPolicy: ExistingWorkPolicy = ExistingWorkPolicy.REPLACE,
|
||||||
) = enqueueKronSchedulerWork(workName, initialScheduler, T::class.java, setUpRequest)
|
noinline setUpRequest: suspend OneTimeWorkRequest.Builder.() -> Unit = {}
|
||||||
|
) = enqueueKronSchedulerWork(workName, initialScheduler, T::class.java, existingWorkPolicy, setUpRequest)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use this class as an super class in case you wish to implement krontab-based enqueuing of works
|
* Use this class as a super class in case you wish to implement krontab-based enqueuing of works
|
||||||
|
*
|
||||||
|
* @see enqueueKronSchedulerWork
|
||||||
|
* @see KrontabTemplateSchedulerWork
|
||||||
*/
|
*/
|
||||||
abstract class KronSchedulerWork(
|
abstract class KronSchedulerWork(
|
||||||
context: Context,
|
context: Context,
|
||||||
@ -52,30 +75,59 @@ abstract class KronSchedulerWork(
|
|||||||
context,
|
context,
|
||||||
workerParams
|
workerParams
|
||||||
) {
|
) {
|
||||||
|
/**
|
||||||
|
* This variable will be used to reorder new work after that one is happen
|
||||||
|
*
|
||||||
|
* @see prolongOnException
|
||||||
|
* @see prolongOnFailure
|
||||||
|
* @see prolongOnSuccess
|
||||||
|
*/
|
||||||
protected abstract val workName: String
|
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
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this to false in case when this work must not be enqueued after successful complete
|
||||||
|
*/
|
||||||
|
protected open val prolongOnSuccess: Boolean = true
|
||||||
|
/**
|
||||||
|
* Set this to false in case when this work must not be enqueued after failure complete
|
||||||
|
*/
|
||||||
|
protected open val prolongOnFailure
|
||||||
|
get() = prolongOnSuccess
|
||||||
|
/**
|
||||||
|
* Set this to false in case when this work must not be enqueued after exception happen
|
||||||
|
*/
|
||||||
|
protected open val prolongOnException = false
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [KronScheduler] of this method will be used to [prolong] this worker
|
||||||
|
*/
|
||||||
protected abstract suspend fun kronScheduler(): KronScheduler?
|
protected abstract suspend fun kronScheduler(): KronScheduler?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is replacement of [doWork]. It is required to wrap work with [prolong]ing and handling of complete
|
||||||
|
* state
|
||||||
|
*/
|
||||||
protected abstract suspend fun onWork(): Result
|
protected abstract suspend fun onWork(): Result
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override this method in case you have some additional settings for future [OneTimeWorkRequest]
|
||||||
|
*/
|
||||||
protected open suspend fun OneTimeWorkRequest.Builder.setUpRequest() {}
|
protected open suspend fun OneTimeWorkRequest.Builder.setUpRequest() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will [enqueueKronSchedulerWork] using [workName], [kronScheduler] and default
|
||||||
|
* [ExistingWorkPolicy.REPLACE]. You can call this method in case you want to enqueue work by yourself, but you must
|
||||||
|
* be sure that you set up to false [prolongOnSuccess], [prolongOnFailure] and [prolongOnException]
|
||||||
|
*/
|
||||||
protected suspend fun prolong() {
|
protected suspend fun prolong() {
|
||||||
val now = DateTime.now()
|
applicationContext.enqueueKronSchedulerWork(
|
||||||
val nextTriggerTime = kronScheduler() ?.let {
|
workName,
|
||||||
if (prolongOnNextAbsent) {
|
kronScheduler() ?: return,
|
||||||
it.nextOrRelative(now)
|
this::class.java
|
||||||
} else {
|
) {
|
||||||
it.next(now)
|
setUpRequest()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val delayMillis = nextTriggerTime ?.minus(now) ?.millisecondsLong ?: return
|
|
||||||
|
|
||||||
applicationContext.enqueueKronSchedulerWork(workName, delayMillis, this::class.java) { setUpRequest() }
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun doWork(): Result {
|
override suspend fun doWork(): Result {
|
||||||
val result = try {
|
val result = try {
|
||||||
@ -86,8 +138,9 @@ abstract class KronSchedulerWork(
|
|||||||
}
|
}
|
||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
if (result !is Result.Failure || prolongOnFailure) {
|
when (result) {
|
||||||
prolong()
|
is Result.Failure -> if (prolongOnFailure) prolong()
|
||||||
|
is Result.Success -> if (prolongOnSuccess) prolong()
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,68 @@
|
|||||||
|
package dev.inmo.krontab
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.work.*
|
||||||
|
|
||||||
|
const val krontabTemplateWorkField = "krontabTemplate"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Will [enqueueKronSchedulerWork] with [KronScheduler] from [krontabTemplate] and call [setUpRequest] on setting up
|
||||||
|
* [OneTimeWorkRequest.Builder] with [Data] which will be used to [OneTimeWorkRequest.Builder.setInputData] after
|
||||||
|
* [setUpRequest] completed
|
||||||
|
*/
|
||||||
|
suspend inline fun <reified T : KrontabTemplateSchedulerWork> Context.enqueueKrontabTemplateSchedulerWork(
|
||||||
|
workName: String,
|
||||||
|
krontabTemplate: KrontabTemplate,
|
||||||
|
existingWorkPolicy: ExistingWorkPolicy = ExistingWorkPolicy.REPLACE,
|
||||||
|
noinline setUpRequest: suspend OneTimeWorkRequest.Builder.(
|
||||||
|
data: Data
|
||||||
|
) -> Unit = {}
|
||||||
|
) = enqueueKronSchedulerWork(workName, krontabTemplate.toKronScheduler(), T::class.java, existingWorkPolicy) {
|
||||||
|
val data = workDataOf(
|
||||||
|
krontabTemplateWorkField to krontabTemplate
|
||||||
|
)
|
||||||
|
setUpRequest(data)
|
||||||
|
setInputData(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extend this class in case you wish to base on [KrontabTemplate]. It will automatically handle request of
|
||||||
|
* [kronScheduler] and put it in [setUpRequest]
|
||||||
|
*/
|
||||||
|
abstract class KrontabTemplateSchedulerWork(
|
||||||
|
context: Context,
|
||||||
|
workerParams: WorkerParameters
|
||||||
|
) : KronSchedulerWork(context, workerParams) {
|
||||||
|
/**
|
||||||
|
* Will try to get [KrontabTemplate] from [getInputData] by key [krontabTemplateWorkField]
|
||||||
|
*
|
||||||
|
* @see setUpRequest
|
||||||
|
*/
|
||||||
|
protected val krontabTemplate: KrontabTemplate?
|
||||||
|
get() = inputData.getString(krontabTemplateWorkField)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override this methods instead of old [setUpRequest] in case you wish to set up some work request parameters
|
||||||
|
*
|
||||||
|
* @param data This parameter will be used to put data inside of [OneTimeWorkRequest.Builder] after this method
|
||||||
|
* will be completed
|
||||||
|
*/
|
||||||
|
protected open suspend fun OneTimeWorkRequest.Builder.setUpRequest(data: Data) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Will automatically put [krontabTemplate] into work data, call [setUpRequest] with future [Data] object and then
|
||||||
|
* call [OneTimeWorkRequest.Builder.setInputData] with that [Data] object
|
||||||
|
*/
|
||||||
|
override suspend fun OneTimeWorkRequest.Builder.setUpRequest() {
|
||||||
|
val data = workDataOf(
|
||||||
|
krontabTemplateWorkField to krontabTemplate,
|
||||||
|
)
|
||||||
|
setUpRequest(data)
|
||||||
|
setInputData(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Will return [KronScheduler] in case if [krontabTemplate] was not null
|
||||||
|
*/
|
||||||
|
override suspend fun kronScheduler(): KronScheduler? = krontabTemplate ?.toKronScheduler()
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user