diff --git a/.gitignore b/.gitignore index e87f660a34c2..fc463d6abcfc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.fleet/ .gradle/ .idea/ out/ diff --git a/build.gradle.kts b/build.gradle.kts index 75aeb1bb4af8..9a4e49e7ad60 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,7 +3,7 @@ import org.gradle.api.tasks.wrapper.Wrapper.DistributionType.ALL plugins { kotlin("jvm") kotlin("plugin.serialization") - id("org.jetbrains.kotlinx.binary-compatibility-validator") version "0.11.1" + id("org.jetbrains.kotlinx.binary-compatibility-validator") version "0.12.0" id("org.jetbrains.dokka") signing diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 9b2c38047469..7cedadc0f347 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -11,8 +11,8 @@ dependencies { val kotlinVersion = "1.7.20" implementation(kotlin("gradle-plugin", kotlinVersion)) implementation(kotlin("serialization", kotlinVersion)) - implementation("org.jetbrains.dokka", "dokka-gradle-plugin", "1.7.10") - implementation("org.jetbrains.kotlinx", "atomicfu-gradle-plugin", "0.18.3") - implementation("com.google.devtools.ksp", "symbol-processing-gradle-plugin", "1.7.20-1.0.6") + implementation("org.jetbrains.dokka", "dokka-gradle-plugin", "1.7.20") + implementation("org.jetbrains.kotlinx", "atomicfu-gradle-plugin", "0.18.5") + implementation("com.google.devtools.ksp", "symbol-processing-gradle-plugin", "1.7.20-1.0.7") implementation(gradleApi()) } diff --git a/common/api/common.api b/common/api/common.api index 62cacab4058f..1a272a3c3b96 100644 --- a/common/api/common.api +++ b/common/api/common.api @@ -8098,6 +8098,10 @@ public final class dev/kord/common/entity/UserPremium$Nitro : dev/kord/common/en public static final field INSTANCE Ldev/kord/common/entity/UserPremium$Nitro; } +public final class dev/kord/common/entity/UserPremium$NitroBasic : dev/kord/common/entity/UserPremium { + public static final field INSTANCE Ldev/kord/common/entity/UserPremium$NitroBasic; +} + public final class dev/kord/common/entity/UserPremium$NitroClassic : dev/kord/common/entity/UserPremium { public static final field INSTANCE Ldev/kord/common/entity/UserPremium$NitroClassic; } diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/UserPremium.kt b/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/UserPremium.kt index 0958586c6690..9c922410ce00 100644 --- a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/UserPremium.kt +++ b/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/UserPremium.kt @@ -55,6 +55,8 @@ public sealed class UserPremium( public object Nitro : UserPremium(2) + public object NitroBasic : UserPremium(3) + internal object Serializer : KSerializer { public override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("dev.kord.common.entity.UserPremium", PrimitiveKind.INT) @@ -66,6 +68,7 @@ public sealed class UserPremium( 0 -> None 1 -> NitroClassic 2 -> Nitro + 3 -> NitroBasic else -> Unknown(value) } } @@ -79,6 +82,7 @@ public sealed class UserPremium( None, NitroClassic, Nitro, + NitroBasic, ) } diff --git a/common/src/main/kotlin/entity/DiscordUser.kt b/common/src/main/kotlin/entity/DiscordUser.kt index e59bc9252205..ada6b2a3883b 100644 --- a/common/src/main/kotlin/entity/DiscordUser.kt +++ b/common/src/main/kotlin/entity/DiscordUser.kt @@ -6,6 +6,7 @@ Entry("None", intValue = 0), Entry("NitroClassic", intValue = 1), Entry("Nitro", intValue = 2), + Entry("NitroBasic", intValue = 3) ], ) diff --git a/gateway/src/main/kotlin/retry/LinearRetry.kt b/gateway/src/main/kotlin/retry/LinearRetry.kt index 2ae114b7a32a..96bb00ec2a5f 100644 --- a/gateway/src/main/kotlin/retry/LinearRetry.kt +++ b/gateway/src/main/kotlin/retry/LinearRetry.kt @@ -5,6 +5,7 @@ import kotlinx.atomicfu.update import kotlinx.coroutines.delay import mu.KotlinLogging import kotlin.time.Duration +import kotlin.time.times private val linearRetryLogger = KotlinLogging.logger { } @@ -27,7 +28,7 @@ public class LinearRetry( require( maxBackoff.minus(firstBackoff).isPositive() ) { "maxBackoff ${maxBackoff.inWholeMilliseconds} ms needs to be bigger than firstBackoff ${firstBackoff.inWholeMilliseconds} ms" } - require(maxTries > 0) { "maxTries needs to be positive but was $maxTries" } + require(maxTries > 1) { "maxTries needs to be greater than 1 but was $maxTries" } } private val tries = atomic(0) @@ -42,10 +43,12 @@ public class LinearRetry( override suspend fun retry() { if (!hasNext) error("max retries exceeded") - tries.incrementAndGet() - var diff = (maxBackoff - firstBackoff).inWholeMilliseconds / maxTries - diff *= tries.value - linearRetryLogger.trace { "retry attempt ${tries.value}, delaying for $diff ms" } + // tries/maxTries ratio * (backOffDiff) = retryProgress + val ratio = tries.getAndIncrement() / (maxTries - 1).toDouble() + val retryProgress = ratio * (maxBackoff - firstBackoff) + val diff = firstBackoff + retryProgress + + linearRetryLogger.trace { "retry attempt ${tries.value}, delaying for $diff" } delay(diff) } diff --git a/gateway/src/test/kotlin/helper/LinearRetryTest.kt b/gateway/src/test/kotlin/helper/LinearRetryTest.kt new file mode 100644 index 000000000000..5143c86af7b4 --- /dev/null +++ b/gateway/src/test/kotlin/helper/LinearRetryTest.kt @@ -0,0 +1,46 @@ +package helper + +import dev.kord.gateway.retry.LinearRetry +import kotlinx.coroutines.test.currentTime +import kotlinx.coroutines.test.runTest +import kotlin.test.Test +import kotlin.time.Duration.Companion.milliseconds +import kotlin.time.Duration.Companion.seconds + +class LinearRetryTest { + + @Test + fun testLinearity() = runTest { + val linearRetry = LinearRetry(1.seconds, 10.seconds, 10) + var i = 0 + val start = currentTime + + while (linearRetry.hasNext) { + linearRetry.retry() + i++ + } + + val end = currentTime + val elapsed = (end - start).milliseconds + + assert(elapsed == 55.seconds) + assert(i == 10) + } + + @Test + fun testExtreme() = runTest { + val linearRetry = LinearRetry(1.seconds, 60.seconds, Int.MAX_VALUE) + var i = 0 + val start = currentTime + + while (linearRetry.hasNext && i < 1000) { + linearRetry.retry() + i++ + } + + val end = currentTime + val elapsed = (end - start).milliseconds + + assert(elapsed == 1000.seconds) + } +} diff --git a/settings.gradle.kts b/settings.gradle.kts index e9d2a3049b41..be1e21865df0 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -73,9 +73,9 @@ fun VersionCatalogBuilder.ktor() { fun VersionCatalogBuilder.common() { version("kotlinx-coroutines", "1.6.4") - library("kotlinx-serialization", "org.jetbrains.kotlinx", "kotlinx-serialization-json").version("1.4.0") + library("kotlinx-serialization", "org.jetbrains.kotlinx", "kotlinx-serialization-json").version("1.4.1") library("kotlinx-coroutines", "org.jetbrains.kotlinx", "kotlinx-coroutines-core").versionRef("kotlinx-coroutines") - library("kotlinx-atomicfu", "org.jetbrains.kotlinx", "atomicfu").version("0.18.3") + library("kotlinx-atomicfu", "org.jetbrains.kotlinx", "atomicfu").version("0.18.5") library("kotlin-logging", "io.github.microutils", "kotlin-logging").version("2.1.23") bundle("common", listOf("kotlinx-serialization", "kotlinx-coroutines", "kotlinx-atomicfu", "kotlin-logging")) @@ -102,7 +102,7 @@ fun VersionCatalogBuilder.tests() { } fun VersionCatalogBuilder.kspProcessors() { - library("ksp-api", "com.google.devtools.ksp", "symbol-processing-api").version("1.7.20-1.0.6") + library("ksp-api", "com.google.devtools.ksp", "symbol-processing-api").version("1.7.20-1.0.7") val kotlinpoet = version("kotlinpoet", "1.12.0") library("kotlinpoet", "com.squareup", "kotlinpoet").versionRef(kotlinpoet) diff --git a/voice/api/voice.api b/voice/api/voice.api index 53c2705a9039..173e0a03b06f 100644 --- a/voice/api/voice.api +++ b/voice/api/voice.api @@ -207,18 +207,6 @@ public final class dev/kord/voice/EncryptionMode : java/lang/Enum { public static fun values ()[Ldev/kord/voice/EncryptionMode; } -public final class dev/kord/voice/EncryptionMode$$serializer : kotlinx/serialization/internal/GeneratedSerializer { - public static final field INSTANCE Ldev/kord/voice/EncryptionMode$$serializer; - public static final synthetic field descriptor Lkotlinx/serialization/descriptors/SerialDescriptor; - public fun childSerializers ()[Lkotlinx/serialization/KSerializer; - public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ldev/kord/voice/EncryptionMode; - public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; - public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; - public fun serialize (Lkotlinx/serialization/encoding/Encoder;Ldev/kord/voice/EncryptionMode;)V - public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V - public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; -} - public final class dev/kord/voice/EncryptionMode$Companion { public final fun serializer ()Lkotlinx/serialization/KSerializer; }