Skip to content

Commit

Permalink
Revert "Deprecate Reset and use Instant"
Browse files Browse the repository at this point in the history
This reverts commit b8b1948.
  • Loading branch information
lukellmann committed Sep 3, 2023
1 parent b8b1948 commit e08adf5
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 145 deletions.
62 changes: 21 additions & 41 deletions rest/api/rest.api
Original file line number Diff line number Diff line change
Expand Up @@ -5934,47 +5934,36 @@ public abstract class dev/kord/rest/ratelimit/RequestResponse {
public static final field Companion Ldev/kord/rest/ratelimit/RequestResponse$Companion;
public abstract fun getBucketKey-JBzVXgM ()Ljava/lang/String;
public abstract fun getRateLimit ()Ldev/kord/rest/ratelimit/RateLimit;
public abstract fun getReset ()Lkotlinx/datetime/Instant;
public abstract synthetic fun getReset-8536Nbg ()Lkotlinx/datetime/Instant;
public abstract fun getReset ()Ldev/kord/rest/ratelimit/Reset;
}

public final class dev/kord/rest/ratelimit/RequestResponse$Accepted : dev/kord/rest/ratelimit/RequestResponse {
public synthetic fun <init> (Ljava/lang/String;Ldev/kord/rest/ratelimit/RateLimit;Lkotlinx/datetime/Instant;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun <init> (Ljava/lang/String;Ldev/kord/rest/ratelimit/RateLimit;Ldev/kord/rest/ratelimit/Reset;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1-JBzVXgM ()Ljava/lang/String;
public final fun component2 ()Ldev/kord/rest/ratelimit/RateLimit;
public final fun component3 ()Lkotlinx/datetime/Instant;
public final synthetic fun component3-Ad4v_Ag ()Lkotlinx/datetime/Instant;
public final fun copy-Rgdz8z0 (Ljava/lang/String;Ldev/kord/rest/ratelimit/RateLimit;Lkotlinx/datetime/Instant;)Ldev/kord/rest/ratelimit/RequestResponse$Accepted;
public static synthetic fun copy-Rgdz8z0$default (Ldev/kord/rest/ratelimit/RequestResponse$Accepted;Ljava/lang/String;Ldev/kord/rest/ratelimit/RateLimit;Lkotlinx/datetime/Instant;ILjava/lang/Object;)Ldev/kord/rest/ratelimit/RequestResponse$Accepted;
public final synthetic fun copy-ociLOyk (Ljava/lang/String;Ldev/kord/rest/ratelimit/RateLimit;Lkotlinx/datetime/Instant;)Ldev/kord/rest/ratelimit/RequestResponse$Accepted;
public static synthetic fun copy-ociLOyk$default (Ldev/kord/rest/ratelimit/RequestResponse$Accepted;Ljava/lang/String;Ldev/kord/rest/ratelimit/RateLimit;Lkotlinx/datetime/Instant;ILjava/lang/Object;)Ldev/kord/rest/ratelimit/RequestResponse$Accepted;
public final fun component3 ()Ldev/kord/rest/ratelimit/Reset;
public final fun copy-Rgdz8z0 (Ljava/lang/String;Ldev/kord/rest/ratelimit/RateLimit;Ldev/kord/rest/ratelimit/Reset;)Ldev/kord/rest/ratelimit/RequestResponse$Accepted;
public static synthetic fun copy-Rgdz8z0$default (Ldev/kord/rest/ratelimit/RequestResponse$Accepted;Ljava/lang/String;Ldev/kord/rest/ratelimit/RateLimit;Ldev/kord/rest/ratelimit/Reset;ILjava/lang/Object;)Ldev/kord/rest/ratelimit/RequestResponse$Accepted;
public fun equals (Ljava/lang/Object;)Z
public fun getBucketKey-JBzVXgM ()Ljava/lang/String;
public fun getRateLimit ()Ldev/kord/rest/ratelimit/RateLimit;
public fun getReset ()Lkotlinx/datetime/Instant;
public synthetic fun getReset-8536Nbg ()Lkotlinx/datetime/Instant;
public synthetic fun getReset-Ad4v_Ag ()Lkotlinx/datetime/Instant;
public fun getReset ()Ldev/kord/rest/ratelimit/Reset;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

public final class dev/kord/rest/ratelimit/RequestResponse$BucketRateLimit : dev/kord/rest/ratelimit/RequestResponse {
public synthetic fun <init> (Ljava/lang/String;Ldev/kord/rest/ratelimit/RateLimit;Lkotlinx/datetime/Instant;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun <init> (Ljava/lang/String;Ldev/kord/rest/ratelimit/RateLimit;Ldev/kord/rest/ratelimit/Reset;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1-M0WuMHw ()Ljava/lang/String;
public final fun component2 ()Ldev/kord/rest/ratelimit/RateLimit;
public final fun component3 ()Lkotlinx/datetime/Instant;
public final synthetic fun component3-Ad4v_Ag ()Lkotlinx/datetime/Instant;
public final fun copy-Ec6c71U (Ljava/lang/String;Ldev/kord/rest/ratelimit/RateLimit;Lkotlinx/datetime/Instant;)Ldev/kord/rest/ratelimit/RequestResponse$BucketRateLimit;
public static synthetic fun copy-Ec6c71U$default (Ldev/kord/rest/ratelimit/RequestResponse$BucketRateLimit;Ljava/lang/String;Ldev/kord/rest/ratelimit/RateLimit;Lkotlinx/datetime/Instant;ILjava/lang/Object;)Ldev/kord/rest/ratelimit/RequestResponse$BucketRateLimit;
public final synthetic fun copy-L_klSFE (Ljava/lang/String;Ldev/kord/rest/ratelimit/RateLimit;Lkotlinx/datetime/Instant;)Ldev/kord/rest/ratelimit/RequestResponse$BucketRateLimit;
public static synthetic fun copy-L_klSFE$default (Ldev/kord/rest/ratelimit/RequestResponse$BucketRateLimit;Ljava/lang/String;Ldev/kord/rest/ratelimit/RateLimit;Lkotlinx/datetime/Instant;ILjava/lang/Object;)Ldev/kord/rest/ratelimit/RequestResponse$BucketRateLimit;
public final fun component3 ()Ldev/kord/rest/ratelimit/Reset;
public final fun copy-Ec6c71U (Ljava/lang/String;Ldev/kord/rest/ratelimit/RateLimit;Ldev/kord/rest/ratelimit/Reset;)Ldev/kord/rest/ratelimit/RequestResponse$BucketRateLimit;
public static synthetic fun copy-Ec6c71U$default (Ldev/kord/rest/ratelimit/RequestResponse$BucketRateLimit;Ljava/lang/String;Ldev/kord/rest/ratelimit/RateLimit;Ldev/kord/rest/ratelimit/Reset;ILjava/lang/Object;)Ldev/kord/rest/ratelimit/RequestResponse$BucketRateLimit;
public fun equals (Ljava/lang/Object;)Z
public synthetic fun getBucketKey-JBzVXgM ()Ljava/lang/String;
public fun getBucketKey-M0WuMHw ()Ljava/lang/String;
public fun getRateLimit ()Ldev/kord/rest/ratelimit/RateLimit;
public fun getReset ()Lkotlinx/datetime/Instant;
public synthetic fun getReset-8536Nbg ()Lkotlinx/datetime/Instant;
public synthetic fun getReset-Ad4v_Ag ()Lkotlinx/datetime/Instant;
public fun getReset ()Ldev/kord/rest/ratelimit/Reset;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}
Expand All @@ -5986,26 +5975,20 @@ public final class dev/kord/rest/ratelimit/RequestResponse$Error : dev/kord/rest
public static final field INSTANCE Ldev/kord/rest/ratelimit/RequestResponse$Error;
public fun getBucketKey-JBzVXgM ()Ljava/lang/String;
public fun getRateLimit ()Ldev/kord/rest/ratelimit/RateLimit;
public fun getReset ()Lkotlinx/datetime/Instant;
public synthetic fun getReset-8536Nbg ()Lkotlinx/datetime/Instant;
public fun getReset ()Ldev/kord/rest/ratelimit/Reset;
}

public final class dev/kord/rest/ratelimit/RequestResponse$GlobalRateLimit : dev/kord/rest/ratelimit/RequestResponse {
public synthetic fun <init> (Ljava/lang/String;Ldev/kord/rest/ratelimit/RateLimit;Lkotlinx/datetime/Instant;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun <init> (Ljava/lang/String;Ldev/kord/rest/ratelimit/RateLimit;Ldev/kord/rest/ratelimit/Reset;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1-JBzVXgM ()Ljava/lang/String;
public final fun component2 ()Ldev/kord/rest/ratelimit/RateLimit;
public final fun component3 ()Lkotlinx/datetime/Instant;
public final synthetic fun component3-Ad4v_Ag ()Lkotlinx/datetime/Instant;
public final fun copy-Rgdz8z0 (Ljava/lang/String;Ldev/kord/rest/ratelimit/RateLimit;Lkotlinx/datetime/Instant;)Ldev/kord/rest/ratelimit/RequestResponse$GlobalRateLimit;
public static synthetic fun copy-Rgdz8z0$default (Ldev/kord/rest/ratelimit/RequestResponse$GlobalRateLimit;Ljava/lang/String;Ldev/kord/rest/ratelimit/RateLimit;Lkotlinx/datetime/Instant;ILjava/lang/Object;)Ldev/kord/rest/ratelimit/RequestResponse$GlobalRateLimit;
public final synthetic fun copy-ociLOyk (Ljava/lang/String;Ldev/kord/rest/ratelimit/RateLimit;Lkotlinx/datetime/Instant;)Ldev/kord/rest/ratelimit/RequestResponse$GlobalRateLimit;
public static synthetic fun copy-ociLOyk$default (Ldev/kord/rest/ratelimit/RequestResponse$GlobalRateLimit;Ljava/lang/String;Ldev/kord/rest/ratelimit/RateLimit;Lkotlinx/datetime/Instant;ILjava/lang/Object;)Ldev/kord/rest/ratelimit/RequestResponse$GlobalRateLimit;
public final fun component3 ()Ldev/kord/rest/ratelimit/Reset;
public final fun copy-Rgdz8z0 (Ljava/lang/String;Ldev/kord/rest/ratelimit/RateLimit;Ldev/kord/rest/ratelimit/Reset;)Ldev/kord/rest/ratelimit/RequestResponse$GlobalRateLimit;
public static synthetic fun copy-Rgdz8z0$default (Ldev/kord/rest/ratelimit/RequestResponse$GlobalRateLimit;Ljava/lang/String;Ldev/kord/rest/ratelimit/RateLimit;Ldev/kord/rest/ratelimit/Reset;ILjava/lang/Object;)Ldev/kord/rest/ratelimit/RequestResponse$GlobalRateLimit;
public fun equals (Ljava/lang/Object;)Z
public fun getBucketKey-JBzVXgM ()Ljava/lang/String;
public fun getRateLimit ()Ldev/kord/rest/ratelimit/RateLimit;
public fun getReset ()Lkotlinx/datetime/Instant;
public synthetic fun getReset-8536Nbg ()Lkotlinx/datetime/Instant;
public synthetic fun getReset-Ad4v_Ag ()Lkotlinx/datetime/Instant;
public fun getReset ()Ldev/kord/rest/ratelimit/Reset;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}
Expand All @@ -6016,17 +5999,14 @@ public abstract interface class dev/kord/rest/ratelimit/RequestToken {
}

public final class dev/kord/rest/ratelimit/Reset {
public static final synthetic fun box-impl (Lkotlinx/datetime/Instant;)Ldev/kord/rest/ratelimit/Reset;
public static fun constructor-impl (Lkotlinx/datetime/Instant;)Lkotlinx/datetime/Instant;
public fun <init> (Lkotlinx/datetime/Instant;)V
public final fun component1 ()Lkotlinx/datetime/Instant;
public final fun copy (Lkotlinx/datetime/Instant;)Ldev/kord/rest/ratelimit/Reset;
public static synthetic fun copy$default (Ldev/kord/rest/ratelimit/Reset;Lkotlinx/datetime/Instant;ILjava/lang/Object;)Ldev/kord/rest/ratelimit/Reset;
public fun equals (Ljava/lang/Object;)Z
public static fun equals-impl (Lkotlinx/datetime/Instant;Ljava/lang/Object;)Z
public static final fun equals-impl0 (Lkotlinx/datetime/Instant;Lkotlinx/datetime/Instant;)Z
public final fun getValue ()Lkotlinx/datetime/Instant;
public fun hashCode ()I
public static fun hashCode-impl (Lkotlinx/datetime/Instant;)I
public fun toString ()Ljava/lang/String;
public static fun toString-impl (Lkotlinx/datetime/Instant;)Ljava/lang/String;
public final synthetic fun unbox-impl ()Lkotlinx/datetime/Instant;
}

public final class dev/kord/rest/ratelimit/Total {
Expand Down
15 changes: 7 additions & 8 deletions rest/src/commonMain/kotlin/ratelimit/AbstractRateLimiter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,23 @@ import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.delay
import kotlinx.coroutines.sync.Mutex
import kotlinx.datetime.Clock
import kotlinx.datetime.Instant
import mu.KLogger
import kotlin.time.Duration.Companion.minutes

public abstract class AbstractRateLimiter internal constructor(public val clock: Clock) : RequestRateLimiter {
internal abstract val logger: KLogger

private val autoBanRateLimiter = IntervalRateLimiter(limit = 25000, interval = 10.minutes)
private val globalSuspensionPoint = atomic(clock.now())
private val globalSuspensionPoint = atomic(Reset(clock.now()))
internal val buckets = ConcurrentHashMap<BucketKey, Bucket>()
private val routeBuckets = ConcurrentHashMap<RequestIdentifier, MutableSet<BucketKey>>()

internal val BucketKey.bucket get() = buckets.getOrPut(this) { Bucket(this) }
private val Request<*, *>.buckets get() = routeBuckets[identifier].orEmpty().map { it.bucket }
internal fun RequestIdentifier.addBucket(id: BucketKey) = routeBuckets.getOrPut(this) { mutableSetOf() }.add(id)

private suspend fun Instant.await() {
val duration = this - clock.now()
internal suspend fun Reset.await() {
val duration = value - clock.now()
if (duration.isNegative()) return
delay(duration)
}
Expand Down Expand Up @@ -67,11 +66,11 @@ public abstract class AbstractRateLimiter internal constructor(public val clock:

when (response) {
is RequestResponse.GlobalRateLimit -> {
logger.trace { "[RATE LIMIT]:[GLOBAL]:exhausted until ${response.reset}" }
logger.trace { "[RATE LIMIT]:[GLOBAL]:exhausted until ${response.reset.value}" }
globalSuspensionPoint.update { response.reset }
}
is RequestResponse.BucketRateLimit -> {
logger.trace { "[RATE LIMIT]:[BUCKET]:Bucket ${response.bucketKey.value} was exhausted until ${response.reset}" }
logger.trace { "[RATE LIMIT]:[BUCKET]:Bucket ${response.bucketKey.value} was exhausted until ${response.reset.value}" }
response.bucketKey.bucket.updateReset(response.reset)
}
is RequestResponse.Accepted, RequestResponse.Error -> {}
Expand All @@ -84,7 +83,7 @@ public abstract class AbstractRateLimiter internal constructor(public val clock:
}

internal inner class Bucket(val id: BucketKey) {
private val reset = atomic(clock.now())
private val reset = atomic(Reset(clock.now()))
private val mutex = Mutex()

suspend fun awaitAndLock() {
Expand All @@ -93,7 +92,7 @@ public abstract class AbstractRateLimiter internal constructor(public val clock:
reset.value.await()
}

fun updateReset(newValue: Instant) {
fun updateReset(newValue: Reset) {
reset.update { newValue }
}

Expand Down
100 changes: 9 additions & 91 deletions rest/src/commonMain/kotlin/ratelimit/RequestRateLimiter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ package dev.kord.rest.ratelimit

import dev.kord.rest.request.Request
import kotlinx.datetime.Instant
import kotlin.DeprecationLevel.HIDDEN
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
import kotlin.js.JsName
import kotlin.jvm.JvmInline

/**
Expand Down Expand Up @@ -69,34 +67,20 @@ public value class BucketKey(public val value: String)
/**
* The [instant][value] when the current bucket gets reset.
*/
@Deprecated(
"Use 'Instant' directly instead.",
ReplaceWith("Instant", "kotlinx.datetime.Instant"),
DeprecationLevel.WARNING,
)
@JvmInline
public value class Reset(public val value: Instant)
public data class Reset(public val value: Instant)

public sealed class RequestResponse {
public abstract val bucketKey: BucketKey?
public abstract val rateLimit: RateLimit?
public abstract val reset: Instant?

@Suppress("FunctionName")
@Deprecated("Binary compatibility, keep for some releases.", level = HIDDEN)
@JsName("getReset")
public abstract fun `getReset-8536Nbg`(): Instant?
public abstract val reset: Reset?

/**
* The request returned a non-rate limit error code.
*/
public object Error : RequestResponse() {
override val bucketKey: BucketKey? = null
override val rateLimit: RateLimit? = null
override val reset: Instant? = null

@Deprecated("Binary compatibility, keep for some releases.", level = HIDDEN)
override fun `getReset-8536Nbg`(): Instant? = reset
override val reset: Reset? = null
}

/**
Expand All @@ -105,92 +89,26 @@ public sealed class RequestResponse {
public data class Accepted(
override val bucketKey: BucketKey?,
override val rateLimit: RateLimit?,
override val reset: Instant,
) : RequestResponse() {
@Suppress("FunctionName")
@Deprecated("Binary compatibility, keep for some releases.", level = HIDDEN)
@JsName("_component3")
public fun `component3-Ad4v_Ag`(): Instant = reset

@Suppress("FunctionName")
@Deprecated("Binary compatibility, keep for some releases.", level = HIDDEN)
@JsName("_copy")
public fun `copy-ociLOyk`(
bucketKey: String? = this.bucketKey?.value,
rateLimit: RateLimit? = this.rateLimit,
reset: Instant = this.reset,
): Accepted = Accepted(bucketKey?.let(::BucketKey), rateLimit, reset)

@Deprecated("Binary compatibility, keep for some releases.", level = HIDDEN)
override fun `getReset-8536Nbg`(): Instant = reset

@Suppress("NON_FINAL_MEMBER_IN_FINAL_CLASS", "FunctionName")
@Deprecated("Binary compatibility, keep for some releases.", level = HIDDEN)
@JsName("_getReset")
public open fun `getReset-Ad4v_Ag`(): Instant = reset
}
override val reset: Reset
) : RequestResponse()

/**
* The request returned a global rate limit error.
*/
public data class GlobalRateLimit(
override val bucketKey: BucketKey?,
override val rateLimit: RateLimit?,
override val reset: Instant,
) : RequestResponse() {
@Suppress("FunctionName")
@Deprecated("Binary compatibility, keep for some releases.", level = HIDDEN)
@JsName("_component3")
public fun `component3-Ad4v_Ag`(): Instant = reset

@Suppress("FunctionName")
@Deprecated("Binary compatibility, keep for some releases.", level = HIDDEN)
@JsName("_copy")
public fun `copy-ociLOyk`(
bucketKey: String? = this.bucketKey?.value,
rateLimit: RateLimit? = this.rateLimit,
reset: Instant = this.reset,
): GlobalRateLimit = GlobalRateLimit(bucketKey?.let(::BucketKey), rateLimit, reset)

@Deprecated("Binary compatibility, keep for some releases.", level = HIDDEN)
override fun `getReset-8536Nbg`(): Instant = reset

@Suppress("NON_FINAL_MEMBER_IN_FINAL_CLASS", "FunctionName")
@Deprecated("Binary compatibility, keep for some releases.", level = HIDDEN)
@JsName("_getReset")
public open fun `getReset-Ad4v_Ag`(): Instant = reset
}
override val reset: Reset
) : RequestResponse()

/**
* The request returned a bucket rate limit error.
*/
public data class BucketRateLimit(
override val bucketKey: BucketKey,
override val rateLimit: RateLimit?,
override val reset: Instant,
) : RequestResponse() {
@Suppress("FunctionName")
@Deprecated("Binary compatibility, keep for some releases.", level = HIDDEN)
@JsName("_component3")
public fun `component3-Ad4v_Ag`(): Instant = reset

@Suppress("FunctionName")
@Deprecated("Binary compatibility, keep for some releases.", level = HIDDEN)
@JsName("_copy")
public fun `copy-L_klSFE`(
bucketKey: String = this.bucketKey.value,
rateLimit: RateLimit? = this.rateLimit,
reset: Instant = this.reset,
): BucketRateLimit = BucketRateLimit(BucketKey(bucketKey), rateLimit, reset)

@Deprecated("Binary compatibility, keep for some releases.", level = HIDDEN)
override fun `getReset-8536Nbg`(): Instant = reset

@Suppress("NON_FINAL_MEMBER_IN_FINAL_CLASS", "FunctionName")
@Deprecated("Binary compatibility, keep for some releases.", level = HIDDEN)
@JsName("_getReset")
public open fun `getReset-Ad4v_Ag`(): Instant = reset
}
override val reset: Reset
) : RequestResponse()

public companion object

Expand Down
2 changes: 1 addition & 1 deletion rest/src/commonMain/kotlin/request/KtorRequestHandler.kt
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public fun RequestResponse.Companion.from(response: HttpResponse, clock: Clock):
RateLimit(total, remaining)
}

val reset = response.channelResetPoint(clock)
val reset = Reset(response.channelResetPoint(clock))

return when {
response.isGlobalRateLimit -> RequestResponse.GlobalRateLimit(bucket, rateLimit, reset)
Expand Down
Loading

0 comments on commit e08adf5

Please sign in to comment.