Compare commits

...

42 Commits

Author SHA1 Message Date
7649d20984 Merge pull request #28 from InsanusMokrassar/0.7.1
0.7.1
2022-02-27 22:08:03 +06:00
ab274636b9 workflows fix 2022-02-27 20:47:10 +06:00
7f2f8a4a26 revert android sdk version 2022-02-27 20:37:48 +06:00
f64171c0f0 update android compile sdk up to 33.0.0 2022-02-27 19:05:07 +06:00
8382108b01 start 0.7.1 2022-02-27 18:20:49 +06:00
32499d02fb Update kdocs.yml 2021-12-25 14:05:13 +06:00
2b06033c75 Merge pull request #25 from InsanusMokrassar/0.7.0
0.7.0
2021-12-25 00:25:16 +06:00
84f1063e3f Update gradle-wrapper.properties 2021-12-24 17:59:39 +06:00
347cf64cb2 Update CHANGELOG.md 2021-12-24 17:59:11 +06:00
eb73da67eb Update gradle.properties 2021-12-23 13:03:16 +06:00
4aadf513aa Update gradle.properties 2021-12-23 13:02:47 +06:00
8c011ea1fb Update publishing_packages.yml 2021-12-22 12:55:22 +06:00
aa9c2b8ea0 Update gradle.properties 2021-12-22 12:52:08 +06:00
adf10301dc Update gradle.properties 2021-12-12 13:37:30 +06:00
7799077e44 Update gradle-wrapper.properties 2021-12-05 10:57:26 +06:00
83339dc095 Update gradle.properties 2021-12-05 10:51:49 +06:00
3040951f37 optimize imports 2021-11-22 19:09:33 +06:00
0bfe022476 update dependencies and remove deprecations 2021-11-22 19:08:24 +06:00
06107f75f2 start 0.7.0 2021-11-22 18:59:44 +06:00
039fe1cb5f Merge pull request #24 from InsanusMokrassar/0.6.6
0.6.6
2021-11-12 16:14:27 +06:00
ea7fab6130 0.6.6 2021-11-12 16:06:08 +06:00
2f3796733d Hotfix for 0.6.5 flows 2021-09-26 14:17:01 +06:00
89a6a305f8 Merge pull request #23 from InsanusMokrassar/0.6.5
0.6.5
2021-09-26 14:08:01 +06:00
97752e1ac0 optimize imports 2021-09-26 13:06:22 +06:00
276ecaac27 overwrite do* extensions 2021-09-26 13:05:59 +06:00
d36e406b59 now flows are using doInfinity 2021-09-26 11:49:01 +06:00
4dc65bf09a delay in doWhile and flows with doWhile instead their own logic 2021-09-25 19:28:49 +06:00
539b5fbcd8 0.6.5 2021-09-25 18:51:51 +06:00
e4f417877d Update kdocs.yml 2021-09-23 13:22:27 +06:00
4f6054c0d9 Update build.gradle 2021-09-23 13:18:40 +06:00
88dbfee370 Update README.md 2021-09-22 20:57:21 +06:00
5af29c2246 Merge pull request #21 from InsanusMokrassar/0.6.4
0.6.4
2021-09-22 20:52:29 +06:00
6aa40ad463 fix publication workflow script 2021-09-22 20:26:12 +06:00
3062f839af fix for publishing packages 2021-09-22 20:20:13 +06:00
001756ab9f add fix for android build 2021-09-22 20:12:50 +06:00
b7ebd0ac1c update workflows 2021-09-22 20:08:06 +06:00
ece767e4d0 update android compile sdk version and build tools 2021-09-22 20:04:08 +06:00
222542b38f update version of build gradle tool 2021-09-22 19:46:35 +06:00
5798774b2d update androidx work dependency 2021-09-22 19:39:18 +06:00
32bf5c0641 update dependencies 2021-09-22 19:34:04 +06:00
5916f3eebb start 0.6.4 2021-09-22 19:29:54 +06:00
df01a66b5a Merge pull request #20 from InsanusMokrassar/0.6.3
0.6.3
2021-08-30 20:26:10 +06:00
14 changed files with 2155 additions and 107 deletions

View File

@@ -10,7 +10,10 @@ jobs:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- uses: actions/setup-java@v1 - uses: actions/setup-java@v1
with: with:
java-version: 1.8 java-version: 11
- name: Fix android 32.0.0 dx
continue-on-error: true
run: cd /usr/local/lib/android/sdk/build-tools/32.0.0/ && cp d8 dx && cd lib && cp d8.jar dx.jar
- name: Build - name: Build
run: ./gradlew dokkaHtml run: ./gradlew dokkaHtml
- name: Publish KDocs - name: Publish KDocs

View File

@@ -7,7 +7,10 @@ jobs:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- uses: actions/setup-java@v1 - uses: actions/setup-java@v1
with: with:
java-version: 1.8 java-version: 11
- name: Fix android 32.0.0 dx
continue-on-error: true
run: cd /usr/local/lib/android/sdk/build-tools/32.0.0/ && cp d8 dx && cd lib && cp d8.jar dx.jar
- name: Update version - name: Update version
run: | run: |
branch="`echo "${{ github.ref }}" | grep -o "[^/]*$"`" branch="`echo "${{ github.ref }}" | grep -o "[^/]*$"`"
@@ -15,7 +18,8 @@ jobs:
- name: prebuild - name: prebuild
run: ./gradlew clean build run: ./gradlew clean build
- name: Publish package - name: Publish package
run: ./gradlew --no-parallel publishAllPublicationsToGithubPackagesRepository -x signJsPublication -x signJvmPublication -x signKotlinMultiplatformPublication -x signAndroidReleasePublication continue-on-error: true
run: ./gradlew --no-parallel publishAllPublicationsToGithubPackagesRepository -x signJsPublication -x signJvmPublication -x signKotlinMultiplatformPublication -x signAndroidReleasePublication -x signAndroidDebugPublication -x signAndroidReleasePublication
env: env:
GITHUBPACKAGES_USER: ${{ github.actor }} GITHUBPACKAGES_USER: ${{ github.actor }}
GITHUBPACKAGES_PASSWORD: ${{ secrets.GITHUB_TOKEN }} GITHUBPACKAGES_PASSWORD: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,12 +0,0 @@
name: Regular build
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
with:
java-version: 1.8
- name: build
run: ./gradlew clean build

View File

@@ -1,5 +1,40 @@
# Changelog # Changelog
## 0.7.1
* Versions
* `Klock`: `2.5.2`
## 0.7.0
**ALL DEPRECATIONS HAVE BEEN REMOVED**
* Versions
* `Kotlin`: `1.6.10`
* `Klock`: `2.4.10`
* `Coroutines`: `1.6.0`
* `Androidx Work`: `2.7.1`
## 0.6.6
* Versions
* `Klock`: `2.4.8`
* `Androidx Work`: `2.7.0`
## 0.6.5
* Flows now use `doWhile` functions
* `doWhile` now use additional delay (for 1 ms) for cases when `block` executing too fast
* New extensions for `KronScheduler`: `do(Once/While/Infinity)Local`/`do(Once/While/Infinity)Tz`
## 0.6.4
* Versions
* `Kotlin`: `1.5.31`
* `Coroutines`: `1.5.2`
* `Klock`: `2.4.2`
* `Androidx Work`: `2.6.0`
## 0.6.3 ## 0.6.3
* Versions * Versions

View File

@@ -1,22 +1,12 @@
# krontab # krontab
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/krontab/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/krontab) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/krontab/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/krontab)
[![Build Status](https://github.com/InsanusMokrassar/krontab/actions/workflows/regular_build.yml/badge.svg)](https://github.com/InsanusMokrassar/krontab/actions/workflows/regular_build.yml) [![Build Status](https://github.com/InsanusMokrassar/krontab/actions/workflows/publishing_packages.yml/badge.svg)](https://github.com/InsanusMokrassar/krontab/actions/workflows/publishing_packages.yml)
[![KDocs](https://raw.githubusercontent.com/InsanusMokrassar/badges/master/kdocs.svg)](https://krontab.inmo.dev/index.html) [![KDocs](https://raw.githubusercontent.com/InsanusMokrassar/badges/master/kdocs.svg)](https://krontab.inmo.dev/index.html)
Library was created to give oppotunity to launch some things from time to time according to some schedule in Library was created to give oppotunity to launch some things from time to time according to some schedule in
runtime of applications. runtime of applications.
| Table of content |
|---|
| [ How to use ](#how-to-use) |
| [ How to use: Including in project ](#including-in-project) |
| [ How to use: Config from string ](#config-from-string) |
| [ How to use: Config via builder (DSL preview) ](#config-via-builder) |
| [ How to use: KronScheduler as a Flow ](#KronScheduler-as-a-Flow) |
| [ How to use: Offsets ](#Offsets) |
| [ How to use: Note about week days ](#Note-about-week-days) |
## How to use ## How to use
There are several ways to configure and use this library: There are several ways to configure and use this library:
@@ -133,6 +123,38 @@ kronScheduler.doInfinity {
All of these examples will do the same things: print `Called` message every five seconds. All of these examples will do the same things: print `Called` message every five seconds.
### do\* functions
With regular `doOnce`/`doWhile`/`doInfinity` there are two types of their variations: **local** and **timezoned**. Local
variations (`doOnceLocal`/`doWhileLocal`/`doInfinityLocal`) will pass `DateTime` as an argument into the block:
```kotlin
doInfinityLocal("/5 * * * *") {
println(it) // will print current date time
}
```
Timezoned variations (`doOnceTz`/`doWhileTz`/`doInfinityTz`) will do the same thing but pass as an argument `DateTimeTz`:
```kotlin
doInfinityTz("/5 * * * * 0o") {
println(it) // will print current date time in UTC
}
```
It is useful in cases when you need to get the time of calling and avoid extra calls to system time.
#### Helpful table for
| | No args | Local `DateTime` | Local `DateTimeTz` with offset of `KronScheduler` |
|---| ------- | ---------------- | ------------------------------------------------- |
| **Call only near time** | doOnce | doOnceLocal | doOnceTz |
| **Call while condition is true** | doWhile | doWhileLocal | doWhileTz |
| **Work infinity*** | doInfinity | doInfinityLocal | doInfinityTz |
*Here there is an important notice, that `Work infinity` is not exactly `infinity`. Actually, that means that `do while
coroutine is alive` and in fact executing will be stopped when coroutine became cancelled.
### KronScheduler as a Flow ### KronScheduler as a Flow
Any `KronScheduler`can e converted to a `Flow<DateTime` using extension `asFlow`: Any `KronScheduler`can e converted to a `Flow<DateTime` using extension `asFlow`:
@@ -163,7 +185,7 @@ flow.takeWhile {
Offsets in this library works via passing parameter ending with `o` in any place after `month` config. Currently Offsets in this library works via passing parameter ending with `o` in any place after `month` config. Currently
there is only one format supported for offsets: minutes of offsets. To use time zones you will need to call `next` there is only one format supported for offsets: minutes of offsets. To use time zones you will need to call `next`
method with `DateTimeTz` argument or `nextTimeZoned` method with any `KronScheduler` instance, but in case if this method with `DateTimeTz` argument or `nextTimeZoned` method with any `KronScheduler` instance, but in case if this
scheduler is not instance of `KronSchedulerTz` it will works like you passed just `DateTime`. scheduler is not instance of `KronSchedulerTz` it will work like you passed just `DateTime`.
Besides, in case you wish to use time zones explicitly, you will need to get `KronSchedulerTz`. It is possible by: Besides, in case you wish to use time zones explicitly, you will need to get `KronSchedulerTz`. It is possible by:

View File

@@ -10,7 +10,7 @@ buildscript {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "com.github.breadmoirai:github-release:$github_release_plugin_version" classpath "com.github.breadmoirai:github-release:$github_release_plugin_version"
classpath "com.getkeepsafe.dexcount:dexcount-gradle-plugin:$dexcount_version" classpath "com.getkeepsafe.dexcount:dexcount-gradle-plugin:$dexcount_version"
classpath 'com.android.tools.build:gradle:4.1.3' classpath 'com.android.tools.build:gradle:7.0.4'
} }
} }
@@ -132,3 +132,8 @@ android {
} }
} }
} }
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}

View File

@@ -8,12 +8,12 @@ android.useAndroidX=true
android.enableJetifier=false android.enableJetifier=false
kotlin_version=1.5.30 kotlin_version=1.6.10
kotlin_coroutines_version=1.5.1 kotlin_coroutines_version=1.6.0
dokka_version=1.5.0 dokka_version=1.6.10
klockVersion=2.4.0 klockVersion=2.5.2
## Github reease ## Github reease
@@ -22,16 +22,16 @@ github_release_plugin_version=2.2.12
## Android ## Android
android_minSdkVersion=19 android_minSdkVersion=19
android_compileSdkVersion=30 android_compileSdkVersion=32
android_buildToolsVersion=30.0.3 android_buildToolsVersion=32.0.0
dexcount_version=3.0.0 dexcount_version=3.0.0
junit_version=4.12 junit_version=4.12
test_ext_junit_version=1.1.2 test_ext_junit_version=1.1.2
espresso_core=3.3.0 espresso_core=3.3.0
androidx_work_version=2.5.0 androidx_work_version=2.7.1
## Common ## Common
version=0.6.3 version=0.7.1
android_code_version=7 android_code_version=12

View File

@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip

1913
kotlin-js-store/yarn.lock Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,10 @@
package dev.inmo.krontab package dev.inmo.krontab
import com.soywiz.klock.DateTime import com.soywiz.klock.DateTime
import com.soywiz.klock.DateTimeTz
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlin.coroutines.coroutineContext
/** /**
* Execute [block] once at the [KronScheduler.next] time and return result of [block] calculation. * Execute [block] once at the [KronScheduler.next] time and return result of [block] calculation.
@@ -10,29 +13,109 @@ import kotlinx.coroutines.delay
* *
* WARNING!!! In case if [KronScheduler.next] of [this] instance will return null, [block] will be called immediately * WARNING!!! In case if [KronScheduler.next] of [this] instance will return null, [block] will be called immediately
*/ */
suspend inline fun <T> KronScheduler.doOnce(noinline block: suspend () -> T): T { suspend inline fun <T> KronScheduler.doOnceLocal(noinline block: suspend (DateTime) -> T): T {
next() ?.let { val time = nextOrNow().also {
delay((it - DateTime.now()).millisecondsLong) delay((it - DateTime.now()).millisecondsLong)
} }
return block() return block(time)
} }
/** /**
* Will [buildSchedule] using [scheduleConfig] and call [doOnce] on it * Execute [block] once at the [KronScheduler.next] time and return result of [block] calculation.
*
* WARNING!!! If you want to launch it in parallel, you must do this explicitly.
*
* WARNING!!! In case if [KronScheduler.next] of [this] instance will return null, [block] will be called immediatelly
*/
suspend inline fun <T> KronScheduler.doOnceTz(noinline block: suspend (DateTimeTz) -> T): T {
val time = when (this) {
is KronSchedulerTz -> nextOrNowWithOffset()
else -> nextOrNow().local
}
delay((time - DateTimeTz.nowLocal()).millisecondsLong)
return block(time)
}
/**
* Execute [block] once at the [KronScheduler.next] time and return result of [block] calculation.
*
* WARNING!!! If you want to launch it in parallel, you must do this explicitly.
*
* WARNING!!! In case if [KronScheduler.next] of [this] instance will return null, [block] will be called immediately
*/
suspend inline fun <T> KronScheduler.doOnce(noinline block: suspend () -> T): T = doOnceLocal { _ -> block() }
/**
* Will [buildSchedule] using [scheduleConfig] and call [doOnceLocal] on it
* @see buildSchedule
*/
suspend inline fun <T> doOnce(
scheduleConfig: String,
noinline block: suspend (DateTime) -> T
) = buildSchedule(scheduleConfig).doOnceLocal(block)
/**
* Will [buildSchedule] using [scheduleConfig] and call [doOnceLocal] on it
* @see buildSchedule
*/
suspend inline fun <T> doOnceTz(
scheduleConfig: String,
noinline block: suspend (DateTimeTz) -> T
) = buildSchedule(scheduleConfig).doOnceTz(block)
/**
* Will [buildSchedule] using [scheduleConfig] and call [doOnceLocal] on it
* @see buildSchedule * @see buildSchedule
*/ */
suspend inline fun <T> doOnce( suspend inline fun <T> doOnce(
scheduleConfig: String, scheduleConfig: String,
noinline block: suspend () -> T noinline block: suspend () -> T
) = buildSchedule(scheduleConfig).doOnce(block) ) = doOnce(scheduleConfig) { _ -> block() }
/** /**
* Will execute [block] while it will return true as a result of its calculation * Will execute [block] while it will return true as a result of its calculation
*/ */
suspend inline fun KronScheduler.doWhile(noinline block: suspend () -> Boolean) { suspend inline fun KronScheduler.doWhileLocal(noinline block: suspend (DateTime) -> Boolean) {
do { val doNext = doOnce(block) } while (doNext) do {
delay(1L)
} while (doOnceLocal(block))
} }
/**
* Will execute [block] while it will return true as a result of its calculation
*/
suspend inline fun KronScheduler.doWhileTz(noinline block: suspend (DateTimeTz) -> Boolean) {
do {
delay(1L)
} while (doOnceTz(block))
}
/**
* Will execute [block] while it will return true as a result of its calculation
*/
suspend inline fun KronScheduler.doWhile(noinline block: suspend () -> Boolean) = doWhileLocal { block() }
/**
* Will [buildSchedule] using [scheduleConfig] and call [doWhile] with [block]
*
* @see buildSchedule
*/
suspend inline fun doWhileLocal(
scheduleConfig: String,
noinline block: suspend (DateTime) -> Boolean
) = buildSchedule(scheduleConfig).doWhileLocal(block)
/**
* Will [buildSchedule] using [scheduleConfig] and call [doWhile] with [block]
*
* @see buildSchedule
*/
suspend inline fun doWhileTz(
scheduleConfig: String,
noinline block: suspend (DateTimeTz) -> Boolean
) = buildSchedule(scheduleConfig).doWhileTz(block)
/** /**
* Will [buildSchedule] using [scheduleConfig] and call [doWhile] with [block] * Will [buildSchedule] using [scheduleConfig] and call [doWhile] with [block]
* *
@@ -41,15 +124,53 @@ suspend inline fun KronScheduler.doWhile(noinline block: suspend () -> Boolean)
suspend inline fun doWhile( suspend inline fun doWhile(
scheduleConfig: String, scheduleConfig: String,
noinline block: suspend () -> Boolean noinline block: suspend () -> Boolean
) = buildSchedule(scheduleConfig).doWhile(block) ) = doWhileLocal(scheduleConfig) { block() }
/**
* Will execute [block] without any checking of result
*/
suspend inline fun KronScheduler.doInfinityLocal(noinline block: suspend (DateTime) -> Unit) = doWhileLocal {
block(it)
coroutineContext.isActive
}
/**
* Will execute [block] without any checking of result
*/
suspend inline fun KronScheduler.doInfinityTz(noinline block: suspend (DateTimeTz) -> Unit) = doWhileTz {
block(it)
coroutineContext.isActive
}
/** /**
* Will execute [block] without any checking of result * Will execute [block] without any checking of result
*/ */
suspend inline fun KronScheduler.doInfinity(noinline block: suspend () -> Unit) = doWhile { suspend inline fun KronScheduler.doInfinity(noinline block: suspend () -> Unit) = doWhile {
block() block()
true coroutineContext.isActive
} }
/**
* Will [buildSchedule] using [scheduleConfig] and call [doInfinity] with [block]
*
* @see buildSchedule
*/
suspend inline fun doInfinityLocal(
scheduleConfig: String,
noinline block: suspend (DateTime) -> Unit
) = buildSchedule(scheduleConfig).doInfinityLocal(block)
/**
* Will [buildSchedule] using [scheduleConfig] and call [doInfinity] with [block]
*
* @see buildSchedule
*/
suspend inline fun doInfinityTz(
scheduleConfig: String,
noinline block: suspend (DateTimeTz) -> Unit
) = buildSchedule(scheduleConfig).doInfinityTz(block)
/** /**
* Will [buildSchedule] using [scheduleConfig] and call [doInfinity] with [block] * Will [buildSchedule] using [scheduleConfig] and call [doInfinity] with [block]
* *

View File

@@ -1,8 +1,8 @@
package dev.inmo.krontab.internal package dev.inmo.krontab.internal
import com.soywiz.klock.* import com.soywiz.klock.DateTime
import com.soywiz.klock.TimezoneOffset
import dev.inmo.krontab.KronScheduler import dev.inmo.krontab.KronScheduler
import dev.inmo.krontab.utils.copy
/** /**
* @param daysOfWeek 0-6 * @param daysOfWeek 0-6

View File

@@ -2,7 +2,6 @@ package dev.inmo.krontab.internal
import com.soywiz.klock.DateTime import com.soywiz.klock.DateTime
import dev.inmo.krontab.KronScheduler import dev.inmo.krontab.KronScheduler
import dev.inmo.krontab.collection.plus
/** /**
* Cron-oriented realisation of [KronScheduler] * Cron-oriented realisation of [KronScheduler]
@@ -36,23 +35,3 @@ internal fun mergeCronDateTimeSchedulers(
): CronDateTimeScheduler = CronDateTimeScheduler( ): CronDateTimeScheduler = CronDateTimeScheduler(
schedulers.map { it.cronDateTime }.merge() schedulers.map { it.cronDateTime }.merge()
) )
/**
* @return New instance of [CronDateTimeScheduler] with all unique [CronDateTimeScheduler.cronDateTimes] of
* [kronSchedulers] included
*/
@Deprecated("Will be removed in next major release", ReplaceWith("merge", "dev.inmo.krontab"))
fun merge(kronSchedulers: List<KronScheduler>) = kronSchedulers.apply { dev.inmo.krontab.merge() }
/**
* @return Vararg shortcut for [dev.inmo.krontab.merge]
*/
@Suppress("NOTHING_TO_INLINE")
@Deprecated("Will be removed in next major release", ReplaceWith("merge", "dev.inmo.krontab"))
inline fun merge(vararg kronDateTimeSchedulers: KronScheduler) = kronDateTimeSchedulers.apply { dev.inmo.krontab.merge() }
/**
* @return Vararg shortcut for [dev.inmo.krontab.merge]
*/
@Suppress("NOTHING_TO_INLINE")
@Deprecated("Will be removed in next major release", ReplaceWith("merge", "dev.inmo.krontab"))
inline fun KronScheduler.plus(other: KronScheduler) = this + other

View File

@@ -1,6 +1,7 @@
package dev.inmo.krontab.utils package dev.inmo.krontab.utils
import com.soywiz.klock.* import com.soywiz.klock.DateTime
import com.soywiz.klock.Month
import kotlin.math.min import kotlin.math.min
fun DateTime.copy( fun DateTime.copy(

View File

@@ -2,57 +2,34 @@ package dev.inmo.krontab.utils
import com.soywiz.klock.DateTime import com.soywiz.klock.DateTime
import com.soywiz.klock.DateTimeTz import com.soywiz.klock.DateTimeTz
import dev.inmo.krontab.KronScheduler import dev.inmo.krontab.*
import dev.inmo.krontab.next import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.* import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.* import kotlinx.coroutines.flow.channelFlow
/** /**
* This [Flow] will trigger emitting each near time which will be returned from [this] [KronScheduler] with attention to * This [Flow] will trigger emitting each near time which will be returned from [this] [KronScheduler] with attention to
* time zones * time zones
* *
* @see channelFlow * @see channelFlow
* @see KronSchedulerTz.doInfinityTz
*/ */
@FlowPreview @FlowPreview
fun KronScheduler.asTzFlow(): Flow<DateTimeTz> = channelFlow { fun KronScheduler.asTzFlow(): Flow<DateTimeTz> = channelFlow {
var previousTime = DateTime.nowLocal() doInfinityTz {
while (isActive) { send(it)
val now = DateTime.nowLocal()
val nextTime = next(now) ?: break
if (previousTime == nextTime) {
delay(1L) // skip 1ms
continue
} else {
previousTime = nextTime
}
val sleepDelay = (nextTime - DateTime.now().local).millisecondsLong
delay(sleepDelay)
send(nextTime)
} }
} }
/** /**
* This method is a map for [asTzFlow] and will works the same but return flow with [DateTime]s * This method is a map for [asTzFlow] and will works the same but return flow with [DateTime]s
*
* @see channelFlow
* @see KronScheduler.doInfinityLocal
*/ */
@FlowPreview @FlowPreview
fun KronScheduler.asFlow(): Flow<DateTime> = asTzFlow().map { it.local } fun KronScheduler.asFlow(): Flow<DateTime> = channelFlow {
doInfinityLocal {
@Deprecated( send(it)
"It is not recommended to use this class in future. This functionality will be removed soon",
ReplaceWith("asFlow", "dev.inmo.krontab.utils.asFlow")
)
@FlowPreview
class SchedulerFlow(
private val scheduler: KronScheduler
) : AbstractFlow<DateTime>() {
@FlowPreview
override suspend fun collectSafely(collector: FlowCollector<DateTime>) {
while (true) {
val now = DateTime.now()
val nextTime = scheduler.next(now) ?: break
val sleepDelay = (nextTime - now).millisecondsLong
delay(sleepDelay)
collector.emit(nextTime)
}
} }
} }