From 763718716d1fc9a600cb0907f0c2a67bc067fd73 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Sun, 4 Sep 2022 15:07:30 +0600 Subject: [PATCH] improve reconnect feature --- .../inmo/plagubot/config/DBConnectOptions.kt | 9 +++++ .../inmo/plagubot/config/DatabaseConfig.kt | 40 +++++++++---------- template.config.json | 5 ++- 3 files changed, 31 insertions(+), 23 deletions(-) create mode 100644 bot/src/main/kotlin/dev/inmo/plagubot/config/DBConnectOptions.kt diff --git a/bot/src/main/kotlin/dev/inmo/plagubot/config/DBConnectOptions.kt b/bot/src/main/kotlin/dev/inmo/plagubot/config/DBConnectOptions.kt new file mode 100644 index 0000000..d072b3f --- /dev/null +++ b/bot/src/main/kotlin/dev/inmo/plagubot/config/DBConnectOptions.kt @@ -0,0 +1,9 @@ +package dev.inmo.plagubot.config + +import kotlinx.serialization.Serializable + +@Serializable +data class DBConnectOptions( + val attempts: Int = 3, + val delay: Long = 1000L +) diff --git a/bot/src/main/kotlin/dev/inmo/plagubot/config/DatabaseConfig.kt b/bot/src/main/kotlin/dev/inmo/plagubot/config/DatabaseConfig.kt index 0291200..6b864b8 100644 --- a/bot/src/main/kotlin/dev/inmo/plagubot/config/DatabaseConfig.kt +++ b/bot/src/main/kotlin/dev/inmo/plagubot/config/DatabaseConfig.kt @@ -1,5 +1,8 @@ package dev.inmo.plagubot.config +import dev.inmo.kslog.common.e +import dev.inmo.kslog.common.logger +import kotlinx.coroutines.delay import kotlinx.serialization.Serializable import kotlinx.serialization.Transient import org.jetbrains.exposed.sql.Database @@ -18,29 +21,22 @@ data class DatabaseConfig( val driver: String = JDBC::class.qualifiedName!!, val username: String = "", val password: String = "", - val waitForConnection: Boolean = true + val reconnectOptions: DBConnectOptions? = DBConnectOptions() ) { @Transient - val database: Database by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { - while (true) { - return@lazy try { - Database.connect( - url, - driver, - username, - password - ).also { - it.transactionManager.defaultIsolationLevel = Connection.TRANSACTION_SERIALIZABLE // Or Connection.TRANSACTION_READ_UNCOMMITTED - } - } catch (e: Throwable) { - if (waitForConnection) { - Thread.sleep(1000L) - continue - } else { - throw e - } + val database: Database = (0 until (reconnectOptions ?.attempts ?: 1)).firstNotNullOfOrNull { + runCatching { + Database.connect( + url, + driver, + username, + password + ).also { + it.transactionManager.defaultIsolationLevel = Connection.TRANSACTION_SERIALIZABLE // Or Connection.TRANSACTION_READ_UNCOMMITTED } - } - error("Unable to get database by some reason") - } + }.onFailure { + logger.e(it) + Thread.sleep(reconnectOptions ?.delay ?: return@onFailure) + }.getOrNull() + } ?: error("Unable to create database") } diff --git a/template.config.json b/template.config.json index ad6d9c5..4d7245f 100644 --- a/template.config.json +++ b/template.config.json @@ -4,7 +4,10 @@ "driver": "org.sqlite.JDBC", "username": "OPTIONAL username", "password": "OPTIONAL password", - "waitForConnection": true + "reconnectOptions": { + "attempts": 3, + "delay": 1000 + } }, "botToken": "1234567890:ABCDEFGHIJKLMNOP_qrstuvwxyz12345678", "plugins": [