diff --git a/ykonsole-mysql/src/main/kotlin/net/aiterp/git/ykonsole2/infrastructure/DataSource.kt b/ykonsole-mysql/src/main/kotlin/net/aiterp/git/ykonsole2/infrastructure/DataSource.kt index 54177e5..351e34e 100644 --- a/ykonsole-mysql/src/main/kotlin/net/aiterp/git/ykonsole2/infrastructure/DataSource.kt +++ b/ykonsole-mysql/src/main/kotlin/net/aiterp/git/ykonsole2/infrastructure/DataSource.kt @@ -3,13 +3,16 @@ package net.aiterp.git.ykonsole2.infrastructure import com.zaxxer.hikari.HikariConfig import com.zaxxer.hikari.HikariDataSource import net.aiterp.git.ykonsole2.InfrastructureException +import net.aiterp.git.ykonsole2.application.logging.log import net.aiterp.git.ykonsole2.domain.models.randomId import org.intellij.lang.annotations.Language import java.sql.Connection import java.sql.PreparedStatement import java.sql.ResultSet import java.sql.SQLException +import java.util.concurrent.TimeUnit import javax.sql.DataSource +import kotlin.time.Duration.Companion.minutes fun makeDataSource( url: String, @@ -23,16 +26,30 @@ fun makeDataSource( cfg.password = password cfg.poolName = "ykonsole2-pool-${randomId()}" cfg.maximumPoolSize = poolSize + cfg.maxLifetime = 5.minutes.inWholeMilliseconds if (driverClassName != null) { cfg.driverClassName = driverClassName } }) -fun DataSource.withConnection(func: Connection.() -> T): T = try { - connection.use(func) -} catch (e: SQLException) { - throw InfrastructureException(e) +fun DataSource.withConnection(func: Connection.() -> T): T { + var health = 3 + + while (true) { + try { + return connection.use(func) + } catch (e: SQLException) { + health-- + log.error("DB error: $e", e) + + if (health <= 0) { + throw InfrastructureException(e) + } + } + + log.info("Trying again") + } } fun Connection.prepare(@Language("MySQL") sql: String, func: PreparedStatement.() -> T): T =