rewrite all onto KronScheduler

This commit is contained in:
InsanusMokrassar 2019-10-10 16:43:52 +06:00
parent 0574c3ba8c
commit 2ce52ade45
7 changed files with 87 additions and 55 deletions

View File

@ -1,25 +1,32 @@
package com.insanusmokrassar.krontab package com.insanusmokrassar.krontab
suspend inline fun CronDateTimeScheduler.executeInfinity(noinline block: suspend () -> Unit) = doInLoop { import com.soywiz.klock.DateTime
import kotlinx.coroutines.delay
suspend inline fun KronScheduler.doWhile(noinline block: suspend () -> Boolean) {
do {
delay(next().unixMillisLong - DateTime.now().unixMillisLong)
} while (block())
}
suspend inline fun doWhile(
scheduleConfig: String,
noinline block: suspend () -> Boolean
) = createSimpleScheduler(scheduleConfig).doWhile(block)
suspend inline fun KronScheduler.doInfinity(noinline block: suspend () -> Unit) = doWhile {
block() block()
true true
} }
suspend inline fun executeInfinity( suspend inline fun doInfinity(
scheduleConfig: String, scheduleConfig: String,
noinline block: suspend () -> Unit noinline block: suspend () -> Unit
) = createCronDateTimeScheduler(scheduleConfig).executeInfinity(block) ) = createSimpleScheduler(scheduleConfig).doInfinity(block)
suspend inline fun CronDateTimeScheduler.executeWhile(noinline block: suspend () -> Boolean) = doInLoop(block) suspend inline fun KronScheduler.doOnce(noinline block: suspend () -> Unit) = doWhile {
suspend inline fun executeWhile(
scheduleConfig: String,
noinline block: suspend () -> Boolean
) = createCronDateTimeScheduler(scheduleConfig).executeWhile(block)
suspend inline fun CronDateTimeScheduler.executeOnce(noinline block: suspend () -> Unit) = doInLoop {
block() block()
false false
} }
suspend inline fun executeOnce( suspend inline fun doOnce(
scheduleConfig: String, scheduleConfig: String,
noinline block: suspend () -> Unit noinline block: suspend () -> Unit
) = createCronDateTimeScheduler(scheduleConfig).executeOnce(block) ) = createSimpleScheduler(scheduleConfig).doOnce(block)

View File

@ -0,0 +1,7 @@
package com.insanusmokrassar.krontab
import com.soywiz.klock.DateTime
interface KronScheduler {
suspend fun next(relatively: DateTime = DateTime.now()): DateTime
}

View File

@ -6,24 +6,24 @@ import com.insanusmokrassar.krontab.internal.CronDateTime
internal val anyCronDateTime by lazy { internal val anyCronDateTime by lazy {
CronDateTime() CronDateTime()
} }
val AnyTimeScheduler by lazy { val AnyTimeScheduler: KronScheduler by lazy {
CronDateTimeScheduler(listOf(anyCronDateTime)) CronDateTimeScheduler(listOf(anyCronDateTime))
} }
val EverySecondScheduler val EverySecondScheduler: KronScheduler
get() = AnyTimeScheduler get() = AnyTimeScheduler
val EveryMinuteScheduler by lazy { val EveryMinuteScheduler: KronScheduler by lazy {
buildSchedule { minutes { 0 every 1 } } buildSchedule { minutes { 0 every 1 } }
} }
val EveryHourScheduler by lazy { val EveryHourScheduler: KronScheduler by lazy {
buildSchedule { hours { 0 every 1 } } buildSchedule { hours { 0 every 1 } }
} }
val EveryDayOfMonthScheduler by lazy { val EveryDayOfMonthScheduler: KronScheduler by lazy {
buildSchedule { dayOfMonth { 0 every 1 } } buildSchedule { dayOfMonth { 0 every 1 } }
} }
val EveryMonthScheduler by lazy { val EveryMonthScheduler: KronScheduler by lazy {
buildSchedule { months { 0 every 1 } } buildSchedule { months { 0 every 1 } }
} }

View File

@ -1,25 +1,39 @@
package com.insanusmokrassar.krontab package com.insanusmokrassar.krontab
import com.insanusmokrassar.krontab.internal.* import com.insanusmokrassar.krontab.internal.*
import com.soywiz.klock.DateTime import com.insanusmokrassar.krontab.internal.CronDateTime
import kotlinx.coroutines.delay import com.insanusmokrassar.krontab.internal.parseDaysOfMonth
import com.insanusmokrassar.krontab.internal.parseHours
import com.insanusmokrassar.krontab.internal.parseMinutes
import com.insanusmokrassar.krontab.internal.parseMonths
import com.insanusmokrassar.krontab.internal.parseSeconds
data class CronDateTimeScheduler internal constructor( /**
internal val cronDateTimes: List<CronDateTime> * Parse [incoming] string and adapt according to next format: "* * * * *" where order of things:
) *
* seconds
fun CronDateTimeScheduler.next(relatively: DateTime = DateTime.now()): DateTime { * minutes
return cronDateTimes.map { it.toNearDateTime(relatively) }.min() ?: anyCronDateTime.toNearDateTime(relatively) * hours
} * dayOfMonth
* month
suspend fun CronDateTimeScheduler.doInLoop(block: suspend () -> Boolean) { *
do { * And each one have next format:
delay(next().unixMillisLong - DateTime.now().unixMillisLong) *
} while (block()) * {number},{number},...
} *
* and {number} here is one of {int}-{int} OR {int}/{int} OR *\/{int} OR {int}.
*
fun createCronDateTimeScheduler(incoming: String): CronDateTimeScheduler { * Seconds ranges can be found in [com.insanusmokrassar.krontab.internal.secondsRange].
* Minutes ranges can be found in [com.insanusmokrassar.krontab.internal.minutesRange].
* Hours ranges can be found in [com.insanusmokrassar.krontab.internal.hoursRange].
* Days of month ranges can be found in [com.insanusmokrassar.krontab.internal.dayOfMonthRange].
* Months ranges can be found in [com.insanusmokrassar.krontab.internal.monthRange].
*
* @sample "0/5 * * * *" for every five seconds triggering
* @sample "0/15 30 * * *" for every 15th seconds in a half of each hour
* @sample "1 2 3 4 5" for triggering in near first second of second minute of third hour of fourth day of may
*/
fun createSimpleScheduler(incoming: String): KronScheduler {
val (secondsSource, minutesSource, hoursSource, dayOfMonthSource, monthSource) = incoming.split(" ") val (secondsSource, minutesSource, hoursSource, dayOfMonthSource, monthSource) = incoming.split(" ")
val secondsParsed = parseSeconds(secondsSource) val secondsParsed = parseSeconds(secondsSource)

View File

@ -1,10 +1,11 @@
package com.insanusmokrassar.krontab.builder package com.insanusmokrassar.krontab.builder
import com.insanusmokrassar.krontab.CronDateTimeScheduler import com.insanusmokrassar.krontab.CronDateTimeScheduler
import com.insanusmokrassar.krontab.KronScheduler
import com.insanusmokrassar.krontab.internal.CronDateTime import com.insanusmokrassar.krontab.internal.CronDateTime
import com.insanusmokrassar.krontab.internal.fillWith import com.insanusmokrassar.krontab.internal.fillWith
fun buildSchedule(settingsBlock: SchedulerBuilder.() -> Unit): CronDateTimeScheduler { fun buildSchedule(settingsBlock: SchedulerBuilder.() -> Unit): KronScheduler {
val builder = SchedulerBuilder() val builder = SchedulerBuilder()
builder.settingsBlock() builder.settingsBlock()
@ -75,7 +76,7 @@ class SchedulerBuilder(
) )
} }
fun build(): CronDateTimeScheduler { fun build(): KronScheduler {
val resultCronDateTimes = mutableListOf(CronDateTime()) val resultCronDateTimes = mutableListOf(CronDateTime())
seconds ?.fillWith(resultCronDateTimes) { previousCronDateTime: CronDateTime, currentTime: Byte -> seconds ?.fillWith(resultCronDateTimes) { previousCronDateTime: CronDateTime, currentTime: Byte ->

View File

@ -0,0 +1,13 @@
package com.insanusmokrassar.krontab
import com.insanusmokrassar.krontab.internal.*
import com.soywiz.klock.DateTime
internal data class CronDateTimeScheduler internal constructor(
internal val cronDateTimes: List<CronDateTime>
) : KronScheduler {
override suspend fun next(relatively: DateTime): DateTime {
return cronDateTimes.map { it.toNearDateTime(relatively) }.min() ?: anyCronDateTime.toNearDateTime(relatively)
}
}

View File

@ -2,7 +2,7 @@ package com.insanusmokrassar.krontab.internal
import com.insanusmokrassar.krontab.utils.clamp import com.insanusmokrassar.krontab.utils.clamp
private fun createCronDateTimeScheduler(from: String, dataRange: IntRange): Array<Byte>? { private fun createSimpleScheduler(from: String, dataRange: IntRange): Array<Byte>? {
val things = from.split(",") val things = from.split(",")
val results = things.flatMap { val results = things.flatMap {
@ -25,21 +25,11 @@ private fun createCronDateTimeScheduler(from: String, dataRange: IntRange): Arra
return results.map { it.toByte() }.toTypedArray() return results.map { it.toByte() }.toTypedArray()
} }
internal fun parseMonths(from: String) = createCronDateTimeScheduler(from, internal fun parseMonths(from: String) = createSimpleScheduler(from, monthRange)
com.insanusmokrassar.krontab.internal.monthRange internal fun parseDaysOfMonth(from: String) = createSimpleScheduler(from, dayOfMonthRange)
) internal fun parseHours(from: String) = createSimpleScheduler(from, hoursRange)
internal fun parseDaysOfMonth(from: String) = createCronDateTimeScheduler(from, internal fun parseMinutes(from: String) = createSimpleScheduler(from, minutesRange)
com.insanusmokrassar.krontab.internal.dayOfMonthRange internal fun parseSeconds(from: String) = createSimpleScheduler(from, secondsRange)
)
internal fun parseHours(from: String) = createCronDateTimeScheduler(from,
com.insanusmokrassar.krontab.internal.hoursRange
)
internal fun parseMinutes(from: String) = createCronDateTimeScheduler(from,
com.insanusmokrassar.krontab.internal.minutesRange
)
internal fun parseSeconds(from: String) = createCronDateTimeScheduler(from,
com.insanusmokrassar.krontab.internal.secondsRange
)
internal fun Array<Byte>.fillWith( internal fun Array<Byte>.fillWith(
whereToPut: MutableList<CronDateTime>, whereToPut: MutableList<CronDateTime>,