Browse Source

Add retry logic

main
Stian Fredrik Aune 2 years ago
parent
commit
8e4cf306a8
  1. 25
      ykonsole-mysql/src/main/kotlin/net/aiterp/git/ykonsole2/infrastructure/DataSource.kt

25
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.HikariConfig
import com.zaxxer.hikari.HikariDataSource import com.zaxxer.hikari.HikariDataSource
import net.aiterp.git.ykonsole2.InfrastructureException import net.aiterp.git.ykonsole2.InfrastructureException
import net.aiterp.git.ykonsole2.application.logging.log
import net.aiterp.git.ykonsole2.domain.models.randomId import net.aiterp.git.ykonsole2.domain.models.randomId
import org.intellij.lang.annotations.Language import org.intellij.lang.annotations.Language
import java.sql.Connection import java.sql.Connection
import java.sql.PreparedStatement import java.sql.PreparedStatement
import java.sql.ResultSet import java.sql.ResultSet
import java.sql.SQLException import java.sql.SQLException
import java.util.concurrent.TimeUnit
import javax.sql.DataSource import javax.sql.DataSource
import kotlin.time.Duration.Companion.minutes
fun makeDataSource( fun makeDataSource(
url: String, url: String,
@ -23,16 +26,30 @@ fun makeDataSource(
cfg.password = password cfg.password = password
cfg.poolName = "ykonsole2-pool-${randomId()}" cfg.poolName = "ykonsole2-pool-${randomId()}"
cfg.maximumPoolSize = poolSize cfg.maximumPoolSize = poolSize
cfg.maxLifetime = 5.minutes.inWholeMilliseconds
if (driverClassName != null) { if (driverClassName != null) {
cfg.driverClassName = driverClassName cfg.driverClassName = driverClassName
} }
}) })
fun <T : Any?> DataSource.withConnection(func: Connection.() -> T): T = try {
connection.use(func)
} catch (e: SQLException) {
throw InfrastructureException(e)
fun <T : Any?> 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 <T : Any?> Connection.prepare(@Language("MySQL") sql: String, func: PreparedStatement.() -> T): T = fun <T : Any?> Connection.prepare(@Language("MySQL") sql: String, func: PreparedStatement.() -> T): T =

Loading…
Cancel
Save