From b7e58be5f83b67e2e37677b8d184bea4a18216c7 Mon Sep 17 00:00:00 2001 From: Marie Ramlow Date: Sun, 21 Aug 2022 22:42:46 +0200 Subject: [PATCH] Fix bug spamming regenbogen-ice api when no next trip is known --- bot/build.gradle.kts | 3 +- bot/src/main/kotlin/RegenbogenICEPlugin.kt | 26 ++++-- .../kotlin/commands/CurrentRideCommand.kt | 3 +- .../main/kotlin/presence/RailTrackPresence.kt | 92 +++++++++---------- gradle/libs.versions.toml | 1 + 5 files changed, 69 insertions(+), 56 deletions(-) diff --git a/bot/build.gradle.kts b/bot/build.gradle.kts index c46a7a1..72c7012 100644 --- a/bot/build.gradle.kts +++ b/bot/build.gradle.kts @@ -24,6 +24,7 @@ dependencies { ksp("com.kotlindiscord.kord.extensions", "annotation-processor", "1.5.5.2-MIKBOT-SNAPSHOT") implementation(libs.marudor) implementation(libs.regenbogen.ice) + implementation(libs.ktor.client.logging) implementation(projects.rwMutex) plugin("dev.schlaubi", "mikbot-health", "1.0.0") } @@ -48,7 +49,7 @@ tasks { bundledPlugins.set(listOf("health@1.0.0", "ktor@2.3.0")) } runBot { - environment["DOWNLOAD_PLUGINS"] = "health@1.0.0,ktor@2.3.0" + environment["DOWNLOAD_PLUGINS"] = "health,ktor" } } diff --git a/bot/src/main/kotlin/RegenbogenICEPlugin.kt b/bot/src/main/kotlin/RegenbogenICEPlugin.kt index 1f68196..f9c5506 100644 --- a/bot/src/main/kotlin/RegenbogenICEPlugin.kt +++ b/bot/src/main/kotlin/RegenbogenICEPlugin.kt @@ -13,26 +13,36 @@ import dev.schlaubi.hafalsch.rainbow_ice.RainbowICE import dev.schlaubi.mikbot.plugin.api.Plugin import dev.schlaubi.mikbot.plugin.api.PluginMain import dev.schlaubi.mikbot.plugin.api.PluginWrapper +import dev.schlaubi.mikbot.plugin.api.config.Config +import dev.schlaubi.mikbot.plugin.api.config.Environment import dev.schlaubi.mikbot.plugin.api.util.AllShardsReadyEvent import io.ktor.client.* import io.ktor.client.engine.okhttp.* import io.ktor.client.plugins.* +import io.ktor.client.plugins.logging.* import kotlinx.coroutines.cancel import org.koin.core.component.inject @PluginMain class RegenbogenICEPlugin(wrapper: PluginWrapper) : Plugin(wrapper) { - private val rainbowICE = RainbowICE { - httpClient = HttpClient(OkHttp) { - install(HttpRequestRetry) { - exponentialDelay() - maxRetries = 20 - retryOnServerErrors(3) - } + private val client = HttpClient(OkHttp) { + install(HttpRequestRetry) { + exponentialDelay() + maxRetries = 20 + retryOnServerErrors(3) } + if (Config.ENVIRONMENT == Environment.DEVELOPMENT) { + install(Logging) + } + } + + private val rainbowICE = RainbowICE { + httpClient = client + } + private val marudor = Marudor { + httpClient = client } - private val marudor = Marudor() override suspend fun ExtensibleBotBuilder.apply() { hooks { diff --git a/bot/src/main/kotlin/commands/CurrentRideCommand.kt b/bot/src/main/kotlin/commands/CurrentRideCommand.kt index ff39b52..f025872 100644 --- a/bot/src/main/kotlin/commands/CurrentRideCommand.kt +++ b/bot/src/main/kotlin/commands/CurrentRideCommand.kt @@ -13,6 +13,7 @@ import dev.kord.x.emoji.Emojis import dev.nycode.regenbogenice.RegenbogenICEExtension import dev.nycode.regenbogenice.command.optionalTrainTrip import dev.nycode.regenbogenice.locale.updateLocaleAsync +import dev.nycode.regenbogenice.presence.REGENBOGEN_ICE_TZN import dev.nycode.regenbogenice.train.TrainOverride import dev.nycode.regenbogenice.train.fetchCurrentTrip import dev.schlaubi.hafalsch.marudor.Marudor @@ -70,7 +71,7 @@ suspend fun RegenbogenICEExtension.currentRideCommand() = action { updateLocaleAsync() val scope = CoroutineScope(Dispatchers.IO) - val (train, currentTrip) = arguments.train ?: fetchCurrentTrip("304") + val (train, currentTrip) = arguments.train ?: fetchCurrentTrip(REGENBOGEN_ICE_TZN) ?: discordError(translate("converter.train.no_trip_data")) val stops = /* just in case it's doch nullable */ currentTrip.safeStops diff --git a/bot/src/main/kotlin/presence/RailTrackPresence.kt b/bot/src/main/kotlin/presence/RailTrackPresence.kt index 609f23c..fcbcd26 100644 --- a/bot/src/main/kotlin/presence/RailTrackPresence.kt +++ b/bot/src/main/kotlin/presence/RailTrackPresence.kt @@ -7,7 +7,6 @@ import dev.nycode.regenbogenice.notification.SentNotification import dev.nycode.regenbogenice.notification.buildNotificationMessage import dev.nycode.regenbogenice.notification.checkNotification import dev.nycode.regenbogenice.notification.notificationCollection -import dev.nycode.regenbogenice.sentry.sentryTransaction import dev.nycode.regenbogenice.train.fetchCurrentTrip import dev.schlaubi.hafalsch.rainbow_ice.entity.TrainVehicle import dev.schlaubi.mikbot.plugin.api.io.Database @@ -24,7 +23,7 @@ import org.litote.kmongo.newId import kotlin.coroutines.CoroutineContext import kotlin.time.Duration.Companion.seconds -private const val REGENBOGEN_ICE_TZN = "304" +const val REGENBOGEN_ICE_TZN = "train:304" class RailTrackPresence(private val kord: Kord, database: Database) : CoroutineScope { override val coroutineContext: CoroutineContext = Dispatchers.IO + SupervisorJob() @@ -37,64 +36,65 @@ class RailTrackPresence(private val kord: Kord, database: Database) : CoroutineS fun start() = launch { runningMutex.withLock { while (isActive) { - val (_, trip) = fetchCurrentTrip(REGENBOGEN_ICE_TZN) - ?: continue - kord.editPresence { - watching("${trip.displayName} to ${trip.destinationStation}") + val information = fetchCurrentTrip(REGENBOGEN_ICE_TZN) + if (information != null) { + val (_, trip) = information + kord.editPresence { + watching("${trip.displayName} to ${trip.destinationStation}") + } + checkNotifications() + } else { + kord.editPresence { + listening("Einfahrtgeräusche") + } } - checkNotifications() delay(30.seconds) } } } private val sentNotifications = database.getCollection("sent_notifications") - private suspend fun checkNotifications() = - sentryTransaction("checkNotifications()", "notifications") { - coroutineScope { - val allNotifications = childTransaction("notifications", "Resolve notifications") { - checkNotification(notificationCollection.find().toList()) - } - val semaphore = Semaphore(6) - allNotifications.forEach { (user, notifications) -> + private suspend fun checkNotifications() { + coroutineScope { + val allNotifications = checkNotification(notificationCollection.find().toList()) + val semaphore = Semaphore(6) + allNotifications.forEach { (user, notifications) -> + launch { semaphore.withPermit { - launch { - childTransaction("notifications", "Resolve notification for user") { - val (days, embeds) = buildNotificationMessage(user, notifications) - ?: return@launch - val existingNotification = - sentNotifications.findOne( - and( - SentNotification::user eq user, - SentNotification::days `in` days, - ) - ) - val channel = kord.getUser(user)?.getDmChannelOrNull() ?: return@launch - if (existingNotification != null) { - channel.getMessageOrNull(existingNotification.messageId)?.edit { - this.embeds = embeds.toMutableList() - } - sentNotifications.save(existingNotification.copy(days = days)) - } else { - val message = channel.createMessage { - this.embeds.addAll(embeds) - } - sentNotifications.save( - SentNotification( - newId(), - user, - message.id, - message.channelId, - days - ) - ) - } + val (days, embeds) = buildNotificationMessage(user, notifications) + ?: return@launch + val existingNotification = + sentNotifications.findOne( + and( + SentNotification::user eq user, + SentNotification::days `in` days, + ) + ) + val channel = kord.getUser(user)?.getDmChannelOrNull() ?: return@launch + if (existingNotification != null) { + channel.getMessageOrNull(existingNotification.messageId)?.edit { + this.embeds = embeds.toMutableList() } + sentNotifications.save(existingNotification.copy(days = days)) + } else { + val message = channel.createMessage { + this.embeds.addAll(embeds) + } + sentNotifications.save( + SentNotification( + newId(), + user, + message.id, + message.channelId, + days + ) + ) } } } } } + } } private val TrainVehicle.Trip.displayName: String diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a265bff..0d8a07e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -9,6 +9,7 @@ ktor-client-js = { module = "io.ktor:ktor-client-js", version.ref = "ktor" } ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" } ktor-client-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" } ktor-client-resources = { module = "io.ktor:ktor-client-resources", version.ref = "ktor" } +ktor-client-logging = { module = "io.ktor:ktor-client-logging", version.ref = "ktor" } kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version = "0.4.0" } marudor = { module = "dev.schlaubi:marudor-client", version = "1.0-SNAPSHOT" } regenbogen-ice = { module = "dev.schlaubi:regenbogen-ice-client", version = "1.0-SNAPSHOT" }