package dev.inmo.krontab.utils import com.soywiz.klock.DateTime import com.soywiz.klock.DateTimeTz import dev.inmo.krontab.KronScheduler import dev.inmo.krontab.next import kotlinx.coroutines.* import kotlinx.coroutines.flow.* /** * This [Flow] will trigger emitting each near time which will be returned from [this] [KronScheduler] with attention to * time zones * * @see channelFlow */ @FlowPreview fun KronScheduler.asTzFlow(): Flow = channelFlow { var previousTime = DateTime.nowLocal() while (isActive) { 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 */ @FlowPreview fun KronScheduler.asFlow(): Flow = asTzFlow().map { it.local } @Deprecated( "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() { @FlowPreview override suspend fun collectSafely(collector: FlowCollector) { while (true) { val now = DateTime.now() val nextTime = scheduler.next(now) ?: break val sleepDelay = (nextTime - now).millisecondsLong delay(sleepDelay) collector.emit(nextTime) } } }