Skip to content

Commit

Permalink
Improve runtime compatibility with kotlin 1.5.31 (#7343)
Browse files Browse the repository at this point in the history
* Revert "Remove usage of toDuration() (#7329)"

This reverts commit 2c93710, as
it doesn't actually solve the problem it was intending to solve.

* Make jvm functions compatible with kotlin 1.5 runtime

Based on the discovery in #7329 (comment)
this commit tries a different approach to make okhttp compatible
with the kotlin 1.5 runtime. Specifically, it converts the DurationUnit
instance to a java.util.concurrent.TimeUnit instance and uses the
existing codepath to handle it. The conversion must be done without
using `DurationUnit.toTimeUnit()` since that is again a function
that would not exist in the 1.5 kotlin runtime environment.
  • Loading branch information
staktrace committed Jun 21, 2022
1 parent 85adee4 commit 3ff1b61
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 20 deletions.
Expand Up @@ -18,9 +18,9 @@

package okhttp3.internal

import kotlin.time.Duration
import kotlin.time.DurationUnit
import kotlin.time.ExperimentalTime
import kotlin.time.toDuration
import okhttp3.CacheControl
import okhttp3.Headers

Expand Down Expand Up @@ -50,20 +50,20 @@ internal fun CacheControl.commonToString(): String {

internal fun CacheControl.Builder.commonMaxAge(maxAge: Int, timeUnit: DurationUnit) = apply {
require(maxAge >= 0) { "maxAge < 0: $maxAge" }
val maxAgeSecondsDouble = Duration.convert(maxAge.toDouble(), timeUnit, DurationUnit.SECONDS)
this.maxAgeSeconds = maxAgeSecondsDouble.commonClampToInt()
val maxAgeSecondsLong = maxAge.toDuration(timeUnit).inWholeSeconds
this.maxAgeSeconds = maxAgeSecondsLong.commonClampToInt()
}

internal fun CacheControl.Builder.commonMaxStale(maxStale: Int, timeUnit: DurationUnit) = apply {
require(maxStale >= 0) { "maxStale < 0: $maxStale" }
val maxStaleSecondsDouble = Duration.convert(maxStale.toDouble(), timeUnit, DurationUnit.SECONDS)
this.maxStaleSeconds = maxStaleSecondsDouble.commonClampToInt()
val maxStaleSecondsLong = maxStale.toDuration(timeUnit).inWholeSeconds
this.maxStaleSeconds = maxStaleSecondsLong.commonClampToInt()
}

internal fun CacheControl.Builder.commonMinFresh(minFresh: Int, timeUnit: DurationUnit) = apply {
require(minFresh >= 0) { "minFresh < 0: $minFresh" }
val minFreshSecondsDouble = Duration.convert(minFresh.toDouble(), timeUnit, DurationUnit.SECONDS)
this.minFreshSeconds = minFreshSecondsDouble.commonClampToInt()
val minFreshSecondsLong = minFresh.toDuration(timeUnit).inWholeSeconds
this.minFreshSeconds = minFreshSecondsLong.commonClampToInt()
}

internal fun Long.commonClampToInt(): Int {
Expand All @@ -73,13 +73,6 @@ internal fun Long.commonClampToInt(): Int {
}
}

internal fun Double.commonClampToInt(): Int {
return when {
this > Int.MAX_VALUE -> Int.MAX_VALUE
else -> toInt()
}
}

internal fun CacheControl.Companion.commonForceNetwork() = CacheControl.Builder()
.noCache()
.build()
Expand Down
16 changes: 10 additions & 6 deletions okhttp/src/jvmMain/kotlin/okhttp3/CacheControl.kt
Expand Up @@ -25,9 +25,6 @@ import okhttp3.internal.commonClampToInt
import okhttp3.internal.commonForceCache
import okhttp3.internal.commonForceNetwork
import okhttp3.internal.commonImmutable
import okhttp3.internal.commonMaxAge
import okhttp3.internal.commonMaxStale
import okhttp3.internal.commonMinFresh
import okhttp3.internal.commonNoCache
import okhttp3.internal.commonNoStore
import okhttp3.internal.commonNoTransform
Expand Down Expand Up @@ -153,11 +150,18 @@ actual class CacheControl internal actual constructor(

actual fun immutable() = commonImmutable()

actual fun maxAge(maxAge: Int, timeUnit: DurationUnit) = commonMaxAge(maxAge, timeUnit)
// We are compiling with kotlin 1.6 but need to run with older versions at runtime. For
// maximum compat we therefore need to handle both the case where DurationUnit is typealiased
// to TimeUnit (as it was pre-1.6) and where it is a distinct wrapper enum (in 1.6). We also
// can't use durationUnit.toTimeUnit() because that doesn't exist in the typealiased case.
// This function should work in either case.
internal fun toJavaTimeUnit(durationUnit: DurationUnit) = TimeUnit.valueOf(durationUnit.name)

actual fun maxStale(maxStale: Int, timeUnit: DurationUnit) = commonMaxStale(maxStale, timeUnit)
actual fun maxAge(maxAge: Int, timeUnit: DurationUnit) = maxAge(maxAge, toJavaTimeUnit(timeUnit))

actual fun minFresh(minFresh: Int, timeUnit: DurationUnit) = commonMinFresh(minFresh, timeUnit)
actual fun maxStale(maxStale: Int, timeUnit: DurationUnit) = maxStale(maxStale, toJavaTimeUnit(timeUnit))

actual fun minFresh(minFresh: Int, timeUnit: DurationUnit) = minFresh(minFresh, toJavaTimeUnit(timeUnit))

/**
* Sets the maximum age of a cached response. If the cache response's age exceeds [maxAge], it
Expand Down

0 comments on commit 3ff1b61

Please sign in to comment.