Compare commits

..

42 Commits

Author SHA1 Message Date
ede47ae664 remove redundant FlowPrevies on flows API 2023-03-18 12:34:06 +06:00
890ab5b15d fill changelogs 2023-03-18 12:24:25 +06:00
5a1ed2f933 start 0.10.0 + rework of flows 2023-03-18 12:23:53 +06:00
7da67386cf Update gradle.properties 2023-03-16 20:00:52 +06:00
7027719fe5 Update gradle-wrapper.properties 2023-03-16 20:00:20 +06:00
a81c7c7c3f Merge pull request #46 from Tolsi/patch-1
typo
2023-03-16 18:20:18 +06:00
Sergey Tolmachev
e5658998d4 typo 2023-03-16 15:16:35 +03:00
6b3cb981ab Merge pull request #45 from InsanusMokrassar/0.9.0
0.9.0
2023-02-28 12:48:51 +06:00
f6518d4d25 add kotlin-js-store folder in gitignore 2023-02-28 12:25:23 +06:00
97a8f39826 update dependencies 2023-02-28 12:24:30 +06:00
469861f7e3 start 0.9.0 2023-02-28 12:23:12 +06:00
69305506ce Update README.md 2023-02-19 16:35:31 +06:00
63ea3f0f1a Merge pull request #44 from InsanusMokrassar/0.8.5
0.8.5
2022-12-15 08:38:54 +06:00
13a8bacb52 fix changelog 2022-12-15 08:37:54 +06:00
9c80e29e71 update autobuild script 2022-12-14 23:00:44 +06:00
cfd2de8fe9 update dependencies 2022-12-14 22:45:34 +06:00
e3490d432e fix in timezoned crontab scheduler 2022-12-14 22:44:27 +06:00
1c95636b71 start 0.8.5 2022-12-14 22:30:34 +06:00
b31a6ab86a Merge pull request #43 from InsanusMokrassar/0.8.4
0.8.4
2022-12-08 09:32:25 +06:00
c35a679827 update kotlin 2022-12-05 15:27:41 +06:00
06f56026db start 0.8.4 2022-12-05 15:26:31 +06:00
54be57d709 Merge pull request #42 from InsanusMokrassar/0.8.3
0.8.3
2022-11-15 10:04:46 +06:00
fae297e4a6 Update CHANGELOG.md 2022-11-14 10:11:46 +06:00
bd81298ac9 Update gradle.properties 2022-11-11 10:25:26 +06:00
cfac5fcd1c Merge pull request #41 from InsanusMokrassar/0.8.2
0.8.2
2022-10-02 22:37:13 +06:00
93d38f8945 Update CHANGELOG.md 2022-10-02 22:26:24 +06:00
97dcd77a8a Update gradle.properties 2022-10-02 22:22:04 +06:00
afa2521b5d Update gradle-wrapper.properties 2022-10-02 22:21:23 +06:00
37b0ec9fb7 start 0.8.2 2022-10-02 11:40:48 +06:00
d36888173a Merge pull request #40 from InsanusMokrassar/0.8.1
0.8.1
2022-09-13 00:58:24 +06:00
30011cd309 Update CHANGELOG.md 2022-09-11 14:18:46 +06:00
fd37a5ddc3 Update gradle.properties 2022-09-11 14:17:48 +06:00
3874f6a42c start 0.8.1 2022-09-11 14:16:52 +06:00
8a98ebd5f9 Merge pull request #39 from InsanusMokrassar/0.8.0
0.8.0
2022-08-06 10:01:18 +06:00
8d0c55129f Update CHANGELOG.md 2022-08-06 09:54:31 +06:00
54b06bf9e6 start 0.8.0 2022-08-06 09:50:59 +06:00
da436ab432 Merge pull request #38 from InsanusMokrassar/0.7.5
0.7.5
2022-07-22 17:09:31 +06:00
154d211514 change kdocs link 2022-07-22 17:09:00 +06:00
0b843ada4f update yarn.lock 2022-07-22 17:03:20 +06:00
25f204a488 update dependencies 2022-07-22 17:00:41 +06:00
2e4ccb9253 start 0.7.5 2022-07-22 16:59:07 +06:00
411a52b85e Update github_release.gradle 2022-07-02 18:38:03 +06:00
23 changed files with 231 additions and 2089 deletions

View File

@@ -8,18 +8,20 @@ jobs:
- uses: actions/setup-java@v1 - uses: actions/setup-java@v1
with: with:
java-version: 11 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 "[^/]*$"`"
sed -i -e "s/^version=\([0-9\.]*\)/version=\1-branch_$branch-build${{ github.run_number }}/" gradle.properties sed -i -e "s/^version=\([0-9\.]*\)/version=\1-branch_$branch-build${{ github.run_number }}/" gradle.properties
- name: prebuild - name: prebuild
run: ./gradlew clean build run: ./gradlew clean build
- name: Publish to Gitea
continue-on-error: true
run: ./gradlew publishAllPublicationsToGiteaRepository
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
- name: Publish package - name: Publish package
continue-on-error: true continue-on-error: true
run: ./gradlew --no-parallel publishAllPublicationsToGithubPackagesRepository -x signJsPublication -x signJvmPublication -x signKotlinMultiplatformPublication -x signAndroidReleasePublication -x signAndroidDebugPublication -x signAndroidReleasePublication run: ./gradlew --no-parallel publishAllPublicationsToGithubPackagesRepository
env: env:
GITHUBPACKAGES_USER: ${{ github.actor }} GITHUBPACKAGES_USER: ${{ github.actor }}
GITHUBPACKAGES_PASSWORD: ${{ secrets.GITHUB_TOKEN }} GITHUBPACKAGES_PASSWORD: ${{ secrets.GITHUB_TOKEN }}

2
.gitignore vendored
View File

@@ -9,4 +9,6 @@ settings.xml
build/ build/
out/ out/
kotlin-js-store/
local.properties local.properties

View File

@@ -1,5 +1,63 @@
# Changelog # Changelog
## 0.10.0
* New extensions for `KronScheduler`:
* `asTzFlowWithoutDelays`/`asFlowWithoutDelays`
* `asTzFlowWithDelays`/`asFlowWithDelays`
* Old `KronScheduler.asFlow` and `KronScheduler.asTzFlow` temporarily marked as deprecated: after several versions their
behaviour will be changed to undelayed one
* All the flow extensions now use `cold` non-channel flows. Potentially it should increase performance and decrease memory usage
## 0.9.0
* Versions
* `Kotlin`: `1.8.10`
* `AndroidXWork`: `2.8.0`
## 0.8.5
* Project is now available in owner `Gitea`: https://git.inmo.dev/InsanusMokrassar/-/packages/maven/dev.inmo-krontab
* `KronSchedulerTz#next` with incoming `DateTime` now will use adjusted local time instead of unadjusted one
* `CronDateTimeSchedulerTz#next` with incoming `DateTime` will convert that parameter to internal offset directly
## 0.8.4
* Versions
* `Kotlin`: `1.7.22`
## 0.8.3
* Versions
* `Kotlin`: `1.7.21`
* `Klock`: `3.4.0`
## 0.8.2
**THIS VERSION HAS CHANGED COMPILE ANDROID SDK FROM 32 -> 33**
* Versions
* `Kotlin`: `1.7.20`
* `Klock`: `3.2.0`
## 0.8.1
* Versions
* `Klock`: `3.1.0`
## 0.8.0
**THIS VERSION HAS CHANGED MIN ANDROID SDK FROM 19 -> 21**
* Versions
* `Kotlin`: `1.7.10`
* `Klock`: `3.0.0`
## 0.7.5
* Versions
* `Coroutines`: `1.6.4`
## 0.7.4 ## 0.7.4
* Versions * Versions

View File

@@ -1,14 +1,14 @@
# 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/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)
![JVM](https://img.shields.io/badge/JVM-red?style=for-the-badge&logo=openjdk&logoColor=white) [![Telegram Chat](https://img.shields.io/badge/Telegram%20Chat-0288D1?style=for-the-badge&logo=telegram&logoColor=white)](https://inmodev_chat.t.me)
![JVM](https://img.shields.io/badge/JVM-red?style=for-the-badge&logo=openjdk&logoColor=white)
![Android](https://img.shields.io/badge/Android-green?style=for-the-badge&logo=android&logoColor=white) ![Android](https://img.shields.io/badge/Android-green?style=for-the-badge&logo=android&logoColor=white)
![Js](https://img.shields.io/badge/JavaScript-323330?style=for-the-badge&logo=javascript&logoColor=F7DF1E) ![Js](https://img.shields.io/badge/JavaScript-323330?style=for-the-badge&logo=javascript&logoColor=F7DF1E)
[![KDocs](https://img.shields.io/badge/KDocs-323330?style=for-the-badge&logo=Kotlin&logoColor=7F52FF)](https://krontab.inmo.dev/index.html) [![KDocs](https://img.shields.io/badge/KDocs-323330?style=for-the-badge&logo=Kotlin&logoColor=7F52FF)](https://insanusmokrassar.github.io/krontab/)
[![Tutorials](https://img.shields.io/badge/Tutorials-0288D1?style=for-the-badge&logo=bookstack&logoColor=white)](https://bookstack.inmo.dev/books/krontab) [![Tutorials](https://img.shields.io/badge/Tutorials-0288D1?style=for-the-badge&logo=bookstack&logoColor=white)](https://bookstack.inmo.dev/books/krontab)
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
@@ -26,7 +26,7 @@ Anyway, to start some action from time to time you will need to use one of exten
```kotlin ```kotlin
val kronScheduler = /* creating of KronScheduler instance */; val kronScheduler = /* creating of KronScheduler instance */;
kronScheuler.doWhile { kronScheduler.doWhile {
// some action // some action
true // true - repeat on next time true // true - repeat on next time
} }

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:7.0.4' classpath 'com.android.tools.build:gradle:7.3.1'
} }
} }
@@ -57,6 +57,7 @@ kotlin {
android { android {
publishAllLibraryVariants() publishAllLibraryVariants()
} }
linuxX64()
sourceSets { sourceSets {
@@ -79,6 +80,7 @@ kotlin {
dependencies { dependencies {
implementation kotlin('test-common') implementation kotlin('test-common')
implementation kotlin('test-annotations-common') implementation kotlin('test-annotations-common')
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$kotlin_coroutines_version"
} }
} }
jvmTest { jvmTest {

View File

@@ -21,7 +21,7 @@ if (new File(projectDir, "secret.gradle").exists()) {
owner "InsanusMokrassar" owner "InsanusMokrassar"
repo "${rootProject.name}" repo "${rootProject.name}"
tagName "${project.version}" tagName "v${project.version}"
releaseName "${project.version}" releaseName "${project.version}"
targetCommitish "${project.version}" targetCommitish "${project.version}"

View File

@@ -1,3 +1,4 @@
org.gradle.jvmargs=-Xmx512m
kotlin.code.style=official kotlin.code.style=official
org.gradle.parallel=true org.gradle.parallel=true
kotlin.js.generate.externals=true kotlin.js.generate.externals=true
@@ -8,12 +9,12 @@ android.useAndroidX=true
android.enableJetifier=false android.enableJetifier=false
kotlin_version=1.6.21 kotlin_version=1.8.10
kotlin_coroutines_version=1.6.3 kotlin_coroutines_version=1.6.4
dokka_version=1.6.21 dokka_version=1.8.10
klockVersion=2.7.0 klockVersion=3.4.0
## Github reease ## Github reease
@@ -21,17 +22,17 @@ github_release_plugin_version=2.4.1
## Android ## Android
android_minSdkVersion=19 android_minSdkVersion=21
android_compileSdkVersion=32 android_compileSdkVersion=33
android_buildToolsVersion=32.0.0 android_buildToolsVersion=33.0.1
dexcount_version=3.0.1 dexcount_version=3.1.0
junit_version=4.12 junit_version=4.12
test_ext_junit_version=1.1.2 test_ext_junit_version=1.1.3
espresso_core=3.3.0 espresso_core=3.4.0
androidx_work_version=2.7.1 androidx_work_version=2.8.0
## Common ## Common
version=0.7.4 version=0.10.0
android_code_version=15 android_code_version=24

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.4-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip

File diff suppressed because it is too large Load Diff

View File

@@ -1 +1 @@
{"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/krontab/blob/master/LICENSE"}],"mavenConfig":{"name":"Krontab","description":"It is an analog of crontab util for Kotlin Coroutines","url":"https://github.com/InsanusMokrassar/krontab","vcsUrl":"https://github.com/InsanusMokrassar/krontab.git","includeGpgSigning":true,"developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}],"repositories":[{"name":"GithubPackages","url":"https://maven.pkg.github.com/InsanusMokrassar/krontab"},{"name":"sonatype","url":"https://oss.sonatype.org/service/local/staging/deploy/maven2/"}]}} {"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/krontab/blob/master/LICENSE"}],"mavenConfig":{"name":"Krontab","description":"It is an analog of crontab util for Kotlin Coroutines","url":"https://github.com/InsanusMokrassar/krontab","vcsUrl":"https://github.com/InsanusMokrassar/krontab.git","developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}],"repositories":[{"name":"GithubPackages","url":"https://maven.pkg.github.com/InsanusMokrassar/krontab"},{"name":"Gitea","url":"https://git.inmo.dev/api/packages/InsanusMokrassar/maven","credsType":{"type":"dev.inmo.kmppscriptbuilder.core.models.MavenPublishingRepository.CredentialsType.HttpHeaderCredentials","headerName":"Authorization","headerValueProperty":"GITEA_TOKEN"}},{"name":"sonatype","url":"https://oss.sonatype.org/service/local/staging/deploy/maven2/"}],"gpgSigning":{"type":"dev.inmo.kmppscriptbuilder.core.models.GpgSigning.Optional"}}}

View File

@@ -1,5 +1,4 @@
apply plugin: 'maven-publish' apply plugin: 'maven-publish'
apply plugin: 'signing'
task javadocsJar(type: Jar) { task javadocsJar(type: Jar) {
classifier = 'javadoc' classifier = 'javadoc'
@@ -43,27 +42,58 @@ publishing {
maven { maven {
name = "GithubPackages" name = "GithubPackages"
url = uri("https://maven.pkg.github.com/InsanusMokrassar/krontab") url = uri("https://maven.pkg.github.com/InsanusMokrassar/krontab")
credentials { credentials {
username = project.hasProperty('GITHUBPACKAGES_USER') ? project.property('GITHUBPACKAGES_USER') : System.getenv('GITHUBPACKAGES_USER') username = project.hasProperty('GITHUBPACKAGES_USER') ? project.property('GITHUBPACKAGES_USER') : System.getenv('GITHUBPACKAGES_USER')
password = project.hasProperty('GITHUBPACKAGES_PASSWORD') ? project.property('GITHUBPACKAGES_PASSWORD') : System.getenv('GITHUBPACKAGES_PASSWORD') password = project.hasProperty('GITHUBPACKAGES_PASSWORD') ? project.property('GITHUBPACKAGES_PASSWORD') : System.getenv('GITHUBPACKAGES_PASSWORD')
} }
}
}
if (project.hasProperty('GITEA_TOKEN') || System.getenv('GITEA_TOKEN') != null) {
maven {
name = "Gitea"
url = uri("https://git.inmo.dev/api/packages/InsanusMokrassar/maven")
credentials(HttpHeaderCredentials) {
name = "Authorization"
value = project.hasProperty('GITEA_TOKEN') ? project.property('GITEA_TOKEN') : System.getenv('GITEA_TOKEN')
}
authentication {
header(HttpHeaderAuthentication)
}
} }
} }
if ((project.hasProperty('SONATYPE_USER') || System.getenv('SONATYPE_USER') != null) && (project.hasProperty('SONATYPE_PASSWORD') || System.getenv('SONATYPE_PASSWORD') != null)) { if ((project.hasProperty('SONATYPE_USER') || System.getenv('SONATYPE_USER') != null) && (project.hasProperty('SONATYPE_PASSWORD') || System.getenv('SONATYPE_PASSWORD') != null)) {
maven { maven {
name = "sonatype" name = "sonatype"
url = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/") url = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/")
credentials { credentials {
username = project.hasProperty('SONATYPE_USER') ? project.property('SONATYPE_USER') : System.getenv('SONATYPE_USER') username = project.hasProperty('SONATYPE_USER') ? project.property('SONATYPE_USER') : System.getenv('SONATYPE_USER')
password = project.hasProperty('SONATYPE_PASSWORD') ? project.property('SONATYPE_PASSWORD') : System.getenv('SONATYPE_PASSWORD') password = project.hasProperty('SONATYPE_PASSWORD') ? project.property('SONATYPE_PASSWORD') : System.getenv('SONATYPE_PASSWORD')
} }
} }
} }
} }
} }
} }
signing { if (project.hasProperty("signing.gnupg.keyName")) {
useGpgCmd() apply plugin: 'signing'
sign publishing.publications
signing {
useGpgCmd()
sign publishing.publications
}
task signAll {
tasks.withType(Sign).forEach {
dependsOn(it)
}
}
} }

View File

@@ -13,7 +13,7 @@ import com.soywiz.klock.DateTimeTz
interface KronSchedulerTz : KronScheduler { interface KronSchedulerTz : KronScheduler {
suspend fun next(relatively: DateTimeTz): DateTimeTz? suspend fun next(relatively: DateTimeTz): DateTimeTz?
override suspend fun next(relatively: DateTime): DateTime? = next(relatively.localUnadjusted) ?.local override suspend fun next(relatively: DateTime): DateTime? = next(relatively.local) ?.local
} }
suspend fun KronSchedulerTz.nextOrRelative(relatively: DateTimeTz): DateTimeTz = next(relatively) ?: getAnyNext( suspend fun KronSchedulerTz.nextOrRelative(relatively: DateTimeTz): DateTimeTz = next(relatively) ?: getAnyNext(

View File

@@ -1,5 +1,6 @@
package dev.inmo.krontab.internal package dev.inmo.krontab.internal
import com.soywiz.klock.DateTime
import com.soywiz.klock.DateTimeTz import com.soywiz.klock.DateTimeTz
import com.soywiz.klock.TimezoneOffset import com.soywiz.klock.TimezoneOffset
import dev.inmo.krontab.KronScheduler import dev.inmo.krontab.KronScheduler
@@ -18,6 +19,10 @@ internal data class CronDateTimeSchedulerTz internal constructor(
val dateTimeWithActualOffset = relatively.toOffset(offset).local val dateTimeWithActualOffset = relatively.toOffset(offset).local
return cronDateTime.toNearDateTime(dateTimeWithActualOffset) ?.toOffsetUnadjusted(offset) ?.toOffset(relatively.offset) return cronDateTime.toNearDateTime(dateTimeWithActualOffset) ?.toOffsetUnadjusted(offset) ?.toOffset(relatively.offset)
} }
override suspend fun next(relatively: DateTime): DateTime? {
return next(relatively.toOffset(offset)) ?.utc
}
} }
internal fun mergeCronDateTimeSchedulers( internal fun mergeCronDateTimeSchedulers(

View File

@@ -2,35 +2,90 @@ 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.* import com.soywiz.klock.milliseconds
import kotlinx.coroutines.FlowPreview import dev.inmo.krontab.KronScheduler
import dev.inmo.krontab.next
import kotlinx.coroutines.currentCoroutineContext
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.channelFlow import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.isActive import kotlinx.coroutines.isActive
/** /**
* This [Flow] will trigger emitting each near time which will be returned from [this] [KronScheduler] with attention to * **This flow is [cold](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/)**
* time zones
* *
* @see channelFlow * Will emit all the [KronScheduler.next] as soon as possible. In case [KronScheduler.next] return null, flow will
* @see KronSchedulerTz.doInfinityTz * be completed
*
* @param since Will be used as the first parameter for [KronScheduler.next] fun
*/ */
@FlowPreview fun KronScheduler.asTzFlowWithoutDelays(since: DateTimeTz = DateTime.nowLocal()): Flow<DateTimeTz> = flow {
fun KronScheduler.asTzFlow(): Flow<DateTimeTz> = channelFlow { var previous = since
doInfinityTz { while (currentCoroutineContext().isActive) {
send(it) val next = next(previous) ?: break
emit(next)
previous = next + 1.milliseconds
} }
} }
/** /**
* This method is a map for [asTzFlow] and will works the same but return flow with [DateTime]s * **This flow is [cold](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/)**
* *
* @see channelFlow * This [Flow] will use [asTzFlowWithoutDelays], but stop on each time until this time will happen
* @see KronScheduler.doInfinity
*/ */
@FlowPreview fun KronScheduler.asTzFlowWithDelays(): Flow<DateTimeTz> = asTzFlowWithoutDelays().onEach { futureHappenTime ->
fun KronScheduler.asFlow(): Flow<DateTime> = channelFlow { val now = DateTime.nowLocal()
doInfinity {
send(it) delay((futureHappenTime - now).millisecondsLong)
}
/**
* **This flow is [cold](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/)**
*
* This [Flow] will use [asTzFlowWithoutDelays], but stop on each time until this time will happen
*/
@Deprecated(
"Behaviour will be changed. In some of near versions this flow will not delay executions",
ReplaceWith("this.asTzFlowWithDelays()", "dev.inmo.krontab.utils.asTzFlowWithDelays")
)
fun KronScheduler.asTzFlow(): Flow<DateTimeTz> = asTzFlowWithDelays()
/**
* **This flow is [cold](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/)**
*
* Will emit all the [KronScheduler.next] as soon as possible. In case [KronScheduler.next] return null, flow will
* be completed
*
* @param since Will be used as the first parameter for [KronScheduler.next] fun
*/
fun KronScheduler.asFlowWithoutDelays(since: DateTime = DateTime.now()): Flow<DateTime> = flow {
var previous = since
while (currentCoroutineContext().isActive) {
val next = next(previous) ?: break
emit(next)
previous = next + 1.milliseconds
} }
} }
/**
* **This flow is [cold](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/)**
*
* This [Flow] will use [asFlowWithoutDelays], but stop on each time until this time will happen
*/
fun KronScheduler.asFlowWithDelays(): Flow<DateTime> = asFlowWithoutDelays().onEach { futureHappenTime ->
val now = DateTime.now()
delay((futureHappenTime - now).millisecondsLong)
}
/**
* **This flow is [cold](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/)**
*
* This [Flow] will use [asFlowWithDelays], but stop on each time until this time will happen
*/
@Deprecated(
"Behaviour will be changed. In some of near versions this flow will not delay executions",
ReplaceWith("this.asFlowWithDelays()", "dev.inmo.krontab.utils.asFlowWithDelays")
)
fun KronScheduler.asFlow(): Flow<DateTime> = asFlowWithDelays()

View File

@@ -3,6 +3,7 @@ package dev.inmo.krontab.utils
import com.soywiz.klock.DateTime import com.soywiz.klock.DateTime
import com.soywiz.klock.days import com.soywiz.klock.days
import dev.inmo.krontab.buildSchedule import dev.inmo.krontab.buildSchedule
import kotlinx.coroutines.test.runTest
import kotlin.test.* import kotlin.test.*
class CheckMonthsAndDaysCorrectWork { class CheckMonthsAndDaysCorrectWork {

View File

@@ -1,6 +1,8 @@
package dev.inmo.krontab.utils package dev.inmo.krontab.utils
import kotlinx.coroutines.* import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
fun CoroutineScope.createFailJob(forTimeMillis: Long) = launch { fun CoroutineScope.createFailJob(forTimeMillis: Long) = launch {
delay(forTimeMillis) delay(forTimeMillis)

View File

@@ -1,8 +0,0 @@
package dev.inmo.krontab.utils
import kotlinx.coroutines.CoroutineScope
/**
* Workaround to use suspending functions in unit tests
*/
expect fun runTest(block: suspend (scope : CoroutineScope) -> Unit)

View File

@@ -2,8 +2,8 @@ package dev.inmo.krontab.utils
import dev.inmo.krontab.builder.buildSchedule import dev.inmo.krontab.builder.buildSchedule
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.takeWhile import kotlinx.coroutines.flow.takeWhile
import kotlinx.coroutines.test.runTest
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
@@ -18,7 +18,7 @@ class SchedulerFlowTests {
} }
} }
val flow = kronScheduler.asFlow() val flow = kronScheduler.asFlowWithoutDelays()
runTest { runTest {
val mustBeCollected = 10 val mustBeCollected = 10
@@ -40,14 +40,14 @@ class SchedulerFlowTests {
} }
} }
val flow = kronScheduler.asFlow() val flow = kronScheduler.asFlowWithoutDelays()
runTest { runTest {
val testsCount = 10 val testsCount = 10
val failJob = it.createFailJob((testsCount * 2) * 1000L) val failJob = createFailJob((testsCount * 2) * 1000L)
val mustBeCollected = 10 val mustBeCollected = 10
val answers = (0 until testsCount).map { _ -> val answers = (0 until testsCount).map { _ ->
it.async { async {
var collected = 0 var collected = 0
flow.takeWhile { flow.takeWhile {
collected < mustBeCollected collected < mustBeCollected

View File

@@ -4,9 +4,8 @@ import com.soywiz.klock.*
import dev.inmo.krontab.KronSchedulerTz import dev.inmo.krontab.KronSchedulerTz
import dev.inmo.krontab.buildSchedule import dev.inmo.krontab.buildSchedule
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.takeWhile import kotlinx.coroutines.flow.takeWhile
import kotlin.math.floor import kotlinx.coroutines.test.runTest
import kotlin.test.* import kotlin.test.*
@ExperimentalCoroutinesApi @ExperimentalCoroutinesApi
@@ -16,7 +15,7 @@ class StringParseTest {
fun testThatFlowIsCorrectlyWorkEverySecondBuiltOnString() { fun testThatFlowIsCorrectlyWorkEverySecondBuiltOnString() {
val kronScheduler = buildSchedule("*/1 * * * *") val kronScheduler = buildSchedule("*/1 * * * *")
val flow = kronScheduler.asFlow() val flow = kronScheduler.asFlowWithoutDelays()
runTest { runTest {
val mustBeCollected = 10 val mustBeCollected = 10
@@ -33,7 +32,7 @@ class StringParseTest {
fun testThatFlowIsCorrectlyWorkEverySecondWhenMillisIsHalfOfSecondBuiltOnString() { fun testThatFlowIsCorrectlyWorkEverySecondWhenMillisIsHalfOfSecondBuiltOnString() {
val kronScheduler = buildSchedule("*/1 * * * * 500ms") val kronScheduler = buildSchedule("*/1 * * * * 500ms")
val flow = kronScheduler.asFlow() val flow = kronScheduler.asFlowWithoutDelays()
runTest { runTest {
val mustBeCollected = 10 val mustBeCollected = 10
@@ -51,14 +50,14 @@ class StringParseTest {
fun testThatFlowIsCorrectlyWorkEverySecondWithMuchOfEmittersBuiltOnString() { fun testThatFlowIsCorrectlyWorkEverySecondWithMuchOfEmittersBuiltOnString() {
val kronScheduler = buildSchedule("*/1 * * * *") val kronScheduler = buildSchedule("*/1 * * * *")
val flow = kronScheduler.asFlow() val flow = kronScheduler.asFlowWithoutDelays()
runTest { runTest {
val testsCount = 10 val testsCount = 10
val failJob = it.createFailJob((testsCount * 2) * 1000L) val failJob = createFailJob((testsCount * 2) * 1000L)
val mustBeCollected = 10 val mustBeCollected = 10
val answers = (0 until testsCount).map { _ -> val answers = (0 until testsCount).map { _ ->
it.async { async {
var collected = 0 var collected = 0
flow.takeWhile { flow.takeWhile {
collected < mustBeCollected collected < mustBeCollected
@@ -81,7 +80,7 @@ class StringParseTest {
val rangesEnds = listOf(0 to 5, 30 to 35) val rangesEnds = listOf(0 to 5, 30 to 35)
val kronScheduler = buildSchedule("${rangesEnds.joinToString(",") { "${it.first}-${it.second}" }} * * * *") val kronScheduler = buildSchedule("${rangesEnds.joinToString(",") { "${it.first}-${it.second}" }} * * * *")
val flow = kronScheduler.asFlow() val flow = kronScheduler.asFlowWithoutDelays()
runTest { runTest {
val ranges = rangesEnds.map { it.first .. it.second }.flatten().distinct().toMutableList() val ranges = rangesEnds.map { it.first .. it.second }.flatten().distinct().toMutableList()
@@ -91,7 +90,10 @@ class StringParseTest {
flow.takeWhile { ranges.isNotEmpty() }.collect { flow.takeWhile { ranges.isNotEmpty() }.collect {
ranges.remove(it.seconds) ranges.remove(it.seconds)
collected++ collected++
assertTrue(collected <= expectedCollects) assertTrue(
collected <= expectedCollects,
"Expected value should be less than $expectedCollects, but was $collected. Ranges state: $ranges"
)
} }
assertEquals(expectedCollects, collected) assertEquals(expectedCollects, collected)
} }

View File

@@ -3,6 +3,7 @@ package dev.inmo.krontab.utils
import com.soywiz.klock.* import com.soywiz.klock.*
import dev.inmo.krontab.builder.buildSchedule import dev.inmo.krontab.builder.buildSchedule
import dev.inmo.krontab.next import dev.inmo.krontab.next
import kotlinx.coroutines.test.runTest
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals

View File

@@ -2,6 +2,7 @@ package dev.inmo.krontab.utils
import com.soywiz.klock.* import com.soywiz.klock.*
import dev.inmo.krontab.builder.buildSchedule import dev.inmo.krontab.builder.buildSchedule
import kotlinx.coroutines.test.runTest
import kotlin.math.ceil import kotlin.math.ceil
import kotlin.test.* import kotlin.test.*

View File

@@ -1,5 +0,0 @@
package dev.inmo.krontab.utils
import kotlinx.coroutines.*
actual fun runTest(block: suspend (scope : CoroutineScope) -> Unit): dynamic = GlobalScope.promise { block(this) }

View File

@@ -1,9 +0,0 @@
package dev.inmo.krontab.utils
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.runBlocking
/**
* Workaround to use suspending functions in unit tests
*/
actual fun runTest(block: suspend (scope: CoroutineScope) -> Unit) = runBlocking(block = block)