Exerosis
07/09/2022, 1:42 AMfun main() = runBlocking {
val component = Component {
var a = 0; var b = 0
every(50.milliseconds) {
if (it % 20 == 0) println("A: ${a++}")
}
every(1.seconds) {
println("B: ${b++}")
}
}
component.enable()
delay(50.seconds)
println("Done!")
}
context(Toggled) @Base
suspend fun every(period: Duration, block: suspend (Int) -> (Unit)) {
simultaneously {
var i = 0
while (isActive) {
block(i++)
delay(period)
}
}
}
The problem with this is that over time the two tasks get way out of sync:
A: 47
B: 49
After 50 secondsFleshgrinder
07/09/2022, 6:32 AMAlejandro Serrano Mena
07/09/2022, 7:23 AMSchedule
https://arrow-kt.io/docs/apidocs/arrow-fx-coroutines/arrow.fx.coroutines/-schedule/Exerosis
07/09/2022, 8:25 AMuli
07/09/2022, 1:02 PMstartTime + i * period - now()
var nextTick : Long = now()
while(isActive()) {
block(nextTick)
nextTick += period
delay(nextTick - now())
}
If you really need i
add as required.Steven Veltema
07/11/2022, 6:10 AMfixedRateTimer
(or NSTimer
on iOS) is the only way to get tight non-drifty periodicity.uli
07/11/2022, 6:28 AMSteven Veltema
07/11/2022, 6:33 AMExerosis
07/11/2022, 5:41 PMSteven Veltema
07/12/2022, 11:55 AMjava.util.Timer
underneath which doesn’t have a real-time guarantee but in my testing it offers more consistent timing than using delay
. Also fixedRateTimer
has the added bonus of being part of the jvm stdlib.uli
07/12/2022, 11:58 AMdelay
probably depend on the thread you schedule on. If you delay on a busy dispatcher you are off. But non of that should cause a drift (i.e. accumulate errors).Exerosis
07/13/2022, 4:42 AMDALDEI
07/27/2022, 11:05 PM