All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jdk8Main.time.Time.kt Maven / Gradle / Ivy

The newest version!
@file:OptIn(ExperimentalContracts::class)

package kotlinx.coroutines.time

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.selects.*
import java.time.*
import java.time.temporal.*
import kotlin.contracts.*

/**
 * "java.time" adapter method for [kotlinx.coroutines.delay].
 */
public suspend fun delay(duration: Duration): Unit = delay(duration.coerceToMillis())

/**
 * "java.time" adapter method for [kotlinx.coroutines.flow.debounce].
 */
@FlowPreview
public fun  Flow.debounce(timeout: Duration): Flow = debounce(timeout.coerceToMillis())

/**
 * "java.time" adapter method for [kotlinx.coroutines.flow.sample].
 */
@FlowPreview
public fun  Flow.sample(period: Duration): Flow = sample(period.coerceToMillis())

/**
 * "java.time" adapter method for [SelectBuilder.onTimeout].
 */
public fun  SelectBuilder.onTimeout(duration: Duration, block: suspend () -> R): Unit =
        onTimeout(duration.coerceToMillis(), block)

/**
 * "java.time" adapter method for [kotlinx.coroutines.withTimeout].
 */
public suspend fun  withTimeout(duration: Duration, block: suspend CoroutineScope.() -> T): T {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return kotlinx.coroutines.withTimeout(duration.coerceToMillis(), block)
}

/**
 * "java.time" adapter method for [kotlinx.coroutines.withTimeoutOrNull].
 */
public suspend fun  withTimeoutOrNull(duration: Duration, block: suspend CoroutineScope.() -> T): T? =
        kotlinx.coroutines.withTimeoutOrNull(duration.coerceToMillis(), block)

/**
 * Coerces the given [Duration] to a millisecond delay.
 * Negative values are coerced to zero, values that cannot
 * be represented in milliseconds as long ("infinite" duration) are coerced to [Long.MAX_VALUE]
 * and durations lesser than a millisecond are coerced to 1 millisecond.
 *
 * The rationale of coercion:
 * 1) Too large durations typically indicate infinity and Long.MAX_VALUE is the
 *    best approximation of infinity we can provide.
 * 2) Coercing too small durations to 1 instead of 0 is crucial for two patterns:
 *    - Programming with deadlines and delays
 *    - Non-suspending fast-paths (e.g. `withTimeout(1 nanosecond) { 42 }` should not throw)
 */
private fun Duration.coerceToMillis(): Long {
    if (this <= Duration.ZERO) return 0
    if (this <= ChronoUnit.MILLIS.duration) return 1

    // Maximum scalar values of Duration.ofMillis(Long.MAX_VALUE)
    val maxSeconds = 9223372036854775
    val maxNanos = 807000000
    return if (seconds < maxSeconds || seconds == maxSeconds && nano < maxNanos) toMillis()
    else Long.MAX_VALUE
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy