Compare commits

..

20 Commits
0.9.0 ... 2.0.0

Author SHA1 Message Date
2004a7dd05 update changelog 2023-05-25 20:53:58 +06:00
7c4217bda6 migration onto new klock and fixes in android manifest 2023-05-25 20:53:10 +06:00
3d6fee7257 migrate onto 2.0.0 due to changes in klock 2023-05-25 20:50:48 +06:00
6cec25eca0 update kotlin version 2023-05-25 20:41:33 +06:00
a0972eaff9 start 1.1.0 2023-05-25 20:38:51 +06:00
cc75501b04 Merge pull request #49 from InsanusMokrassar/1.0.0
1.0.0
2023-04-25 00:28:01 +06:00
89e500ff33 Merge pull request #48 from InsanusMokrassar/renovate/configure
Configure Renovate
2023-04-25 00:15:38 +06:00
a61cd61602 update dependencies 2023-04-25 00:15:13 +06:00
renovate[bot]
5fdb2ea049 Add renovate.json 2023-04-24 18:11:35 +00:00
68ed562b19 start 1.0.0 2023-04-25 00:10:11 +06:00
87b5dfe1aa Update README.md 2023-04-03 16:18:18 +06:00
6a6bfe0552 Merge pull request #47 from InsanusMokrassar/0.10.0
0.10.0
2023-03-18 14:01:14 +06:00
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
36 changed files with 177 additions and 103 deletions

View File

@@ -1,5 +1,27 @@
# Changelog
## 2.0.0
* Versions
* `Kotlin`: `1.8.21`
* `Klock`: `4.0.1`
* Support of `mingwx64` platform
## 1.0.0
* Versions
* `Kotlin`: `1.8.20`
* `AndroidXWork`: `2.8.1`
## 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

View File

@@ -7,6 +7,7 @@
![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)
![Js](https://img.shields.io/badge/JavaScript-323330?style=for-the-badge&logo=javascript&logoColor=F7DF1E)
![Linux x64](https://img.shields.io/badge/Linux%20x64-white?style=for-the-badge&logo=linux&logoColor=black)
[![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)
@@ -26,7 +27,7 @@ Anyway, to start some action from time to time you will need to use one of exten
```kotlin
val kronScheduler = /* creating of KronScheduler instance */;
kronScheuler.doWhile {
kronScheduler.doWhile {
// some action
true // true - repeat on next time
}

View File

@@ -10,7 +10,7 @@ buildscript {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "com.github.breadmoirai:github-release:$github_release_plugin_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:$android_gradle_version"
}
}
@@ -57,6 +57,8 @@ kotlin {
android {
publishAllLibraryVariants()
}
linuxX64()
mingwX64()
sourceSets {
@@ -79,6 +81,7 @@ kotlin {
dependencies {
implementation kotlin('test-common')
implementation kotlin('test-annotations-common')
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$kotlin_coroutines_version"
}
}
jvmTest {
@@ -102,8 +105,9 @@ kotlin {
apply plugin: 'com.getkeepsafe.dexcount'
android {
compileSdkVersion "$android_compileSdkVersion".toInteger()
compileSdk "$android_compileSdkVersion".toInteger()
buildToolsVersion "$android_buildToolsVersion"
namespace "${group}.${project.name}"
defaultConfig {
minSdkVersion "$android_minSdkVersion".toInteger()

View File

@@ -1,3 +1,4 @@
org.gradle.jvmargs=-Xmx512m
kotlin.code.style=official
org.gradle.parallel=true
kotlin.js.generate.externals=true
@@ -8,12 +9,12 @@ android.useAndroidX=true
android.enableJetifier=false
kotlin_version=1.8.10
kotlin_version=1.8.21
kotlin_coroutines_version=1.6.4
dokka_version=1.7.20
dokka_version=1.8.10
klockVersion=3.4.0
klockVersion=4.0.1
## Github reease
@@ -21,17 +22,18 @@ github_release_plugin_version=2.4.1
## Android
android_gradle_version=7.4.2
android_minSdkVersion=21
android_compileSdkVersion=33
android_buildToolsVersion=33.0.1
dexcount_version=3.1.0
android_buildToolsVersion=33.0.2
dexcount_version=4.0.0
junit_version=4.12
test_ext_junit_version=1.1.3
espresso_core=3.4.0
androidx_work_version=2.8.0
androidx_work_version=2.8.1
## Common
version=0.9.0
android_code_version=23
version=2.0.0
android_code_version=26

View File

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

6
renovate.json Normal file
View File

@@ -0,0 +1,6 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:base"
]
}

View File

@@ -1,7 +1,7 @@
package dev.inmo.krontab
import com.soywiz.klock.DateTime
import com.soywiz.klock.DateTimeTz
import korlibs.time.DateTime
import korlibs.time.DateTimeTz
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlin.coroutines.coroutineContext

View File

@@ -1,6 +1,6 @@
package dev.inmo.krontab
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
/**
* This interface was created for abstraction of [next] operation. Currently, there is only

View File

@@ -1,7 +1,7 @@
package dev.inmo.krontab
import com.soywiz.klock.DateTime
import com.soywiz.klock.DateTimeTz
import korlibs.time.DateTime
import korlibs.time.DateTimeTz
/**
* This interface extending [KronScheduler] to use [DateTimeTz] with taking into account offset of incoming time for

View File

@@ -1,6 +1,6 @@
package dev.inmo.krontab
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
class LambdaKronScheduler(
private val onNext: suspend (DateTime) -> DateTime?

View File

@@ -1,6 +1,6 @@
package dev.inmo.krontab
import com.soywiz.klock.DateTimeTz
import korlibs.time.DateTimeTz
class LambdaKronSchedulerTz(
private val onNext: suspend (DateTimeTz) -> DateTimeTz?

View File

@@ -1,6 +1,6 @@
package dev.inmo.krontab
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.krontab.builder.buildSchedule
import dev.inmo.krontab.internal.*

View File

@@ -1,7 +1,7 @@
package dev.inmo.krontab
import com.soywiz.klock.TimezoneOffset
import com.soywiz.klock.minutes
import korlibs.time.TimezoneOffset
import korlibs.time.minutes
import dev.inmo.krontab.internal.*
import dev.inmo.krontab.utils.Minutes

View File

@@ -1,7 +1,7 @@
package dev.inmo.krontab.builder
import com.soywiz.klock.TimezoneOffset
import com.soywiz.klock.minutes
import korlibs.time.TimezoneOffset
import korlibs.time.minutes
import dev.inmo.krontab.KronScheduler
import dev.inmo.krontab.KronSchedulerTz
import dev.inmo.krontab.internal.*

View File

@@ -1,7 +1,7 @@
package dev.inmo.krontab.collection
import com.soywiz.klock.DateTime
import com.soywiz.klock.DateTimeTz
import korlibs.time.DateTime
import korlibs.time.DateTimeTz
import dev.inmo.krontab.*
import dev.inmo.krontab.internal.*

View File

@@ -1,7 +1,7 @@
package dev.inmo.krontab.internal
import com.soywiz.klock.DateTime
import com.soywiz.klock.TimezoneOffset
import korlibs.time.DateTime
import korlibs.time.TimezoneOffset
import dev.inmo.krontab.KronScheduler
/**

View File

@@ -1,6 +1,6 @@
package dev.inmo.krontab.internal
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import dev.inmo.krontab.KronScheduler
/**

View File

@@ -1,8 +1,8 @@
package dev.inmo.krontab.internal
import com.soywiz.klock.DateTime
import com.soywiz.klock.DateTimeTz
import com.soywiz.klock.TimezoneOffset
import korlibs.time.DateTime
import korlibs.time.DateTimeTz
import korlibs.time.TimezoneOffset
import dev.inmo.krontab.KronScheduler
import dev.inmo.krontab.KronSchedulerTz

View File

@@ -1,6 +1,6 @@
package dev.inmo.krontab.internal
import com.soywiz.klock.*
import korlibs.time.*
import dev.inmo.krontab.utils.copy
import kotlin.math.min

View File

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

View File

@@ -1,36 +1,91 @@
package dev.inmo.krontab.utils
import com.soywiz.klock.DateTime
import com.soywiz.klock.DateTimeTz
import dev.inmo.krontab.*
import kotlinx.coroutines.FlowPreview
import korlibs.time.DateTime
import korlibs.time.DateTimeTz
import korlibs.time.milliseconds
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.channelFlow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.isActive
/**
* This [Flow] will trigger emitting each near time which will be returned from [this] [KronScheduler] with attention to
* time zones
* **This flow is [cold](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/)**
*
* @see channelFlow
* @see KronSchedulerTz.doInfinityTz
* 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
*/
@FlowPreview
fun KronScheduler.asTzFlow(): Flow<DateTimeTz> = channelFlow {
doInfinityTz {
send(it)
fun KronScheduler.asTzFlowWithoutDelays(since: DateTimeTz = DateTime.nowLocal()): Flow<DateTimeTz> = flow {
var previous = since
while (currentCoroutineContext().isActive) {
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
* @see KronScheduler.doInfinity
* This [Flow] will use [asTzFlowWithoutDelays], but stop on each time until this time will happen
*/
@FlowPreview
fun KronScheduler.asFlow(): Flow<DateTime> = channelFlow {
doInfinity {
send(it)
fun KronScheduler.asTzFlowWithDelays(): Flow<DateTimeTz> = asTzFlowWithoutDelays().onEach { futureHappenTime ->
val now = DateTime.nowLocal()
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

@@ -1,6 +1,6 @@
package dev.inmo.krontab.utils.flows
import com.soywiz.klock.*
import korlibs.time.*
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filter

View File

@@ -1,6 +1,6 @@
package dev.inmo.krontab.utils.flows
import com.soywiz.klock.*
import korlibs.time.*
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filter

View File

@@ -1,6 +1,6 @@
package dev.inmo.krontab.utils.flows
import com.soywiz.klock.*
import korlibs.time.*
import kotlinx.coroutines.flow.Flow
@Suppress("NOTHING_TO_INLINE")

View File

@@ -1,6 +1,6 @@
package dev.inmo.krontab.utils.flows
import com.soywiz.klock.*
import korlibs.time.*
import kotlinx.coroutines.flow.Flow
@Suppress("NOTHING_TO_INLINE")

View File

@@ -1,8 +1,9 @@
package dev.inmo.krontab.utils
import com.soywiz.klock.DateTime
import com.soywiz.klock.days
import korlibs.time.DateTime
import korlibs.time.days
import dev.inmo.krontab.buildSchedule
import kotlinx.coroutines.test.runTest
import kotlin.test.*
class CheckMonthsAndDaysCorrectWork {

View File

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

View File

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

View File

@@ -1,8 +1,9 @@
package dev.inmo.krontab.utils
import com.soywiz.klock.*
import korlibs.time.*
import dev.inmo.krontab.builder.buildSchedule
import dev.inmo.krontab.next
import kotlinx.coroutines.test.runTest
import kotlin.test.Test
import kotlin.test.assertEquals

View File

@@ -1,7 +1,8 @@
package dev.inmo.krontab.utils
import com.soywiz.klock.*
import korlibs.time.*
import dev.inmo.krontab.builder.buildSchedule
import kotlinx.coroutines.test.runTest
import kotlin.math.ceil
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)

View File

@@ -1 +0,0 @@
<manifest package="dev.inmo.krontab"/>

View File

@@ -2,7 +2,7 @@ package dev.inmo.krontab
import android.content.Context
import androidx.work.*
import com.soywiz.klock.DateTime
import korlibs.time.DateTime
import java.util.concurrent.TimeUnit
/**