Open gaeljw opened 7 months ago
Adding that using ZIO.attemptBlocking
instead ofZIO.attempt
when opening the connection does not change the behavior. I thought it could be related but it's not.
The piece of code that relates to this in zio-jdbc is https://github.com/zio/zio-jdbc/blob/cfd8a7e03491da207fe6cd81cd999cd96080cec2/core/src/main/scala/zio/jdbc/ZConnectionPool.scala#L115-L122
And the default retry config is supposed to be max 10 times: https://github.com/zio/zio-jdbc/blob/cfd8a7e03491da207fe6cd81cd999cd96080cec2/core/src/main/scala/zio/jdbc/ZConnectionPoolConfig.scala#L35-L36
For anyone stumbling across this, I would like to offer some more insights. From my understanding, what is actually happening are not actually infinite retries, but instead the retry policy of the connection pool is applied to every potentially available connection from the pool. To illustrate what I mean consider the below scala-cli script:
#!/usr/bin/env -S scala-cli shebang
//> using dep "dev.zio::zio-jdbc:0.1.2"
//> using dep "dev.zio::zio-streams:2.1.6"
//> using dep "dev.zio::zio:2.1.6"
//> using dep "org.postgresql:postgresql:42.7.3"
import zio.*
import zio.jdbc.*
import zio.stream.*
object App extends ZIOAppDefault:
val retryPolicy = Schedule.stop.tapOutput(_ => ZIO.logInfo("failed"))
val connectionPoolConfig =
ZLayer.succeed:
ZConnectionPoolConfig
.default
.copy(
minConnections = 0,
maxConnections = 1,
retryPolicy = retryPolicy,
)
val connectionPool =
val props = Map("user" -> "postgres", "password" -> "password")
ZConnectionPool.postgres("postgres", 5432, "postgres", props)
val query = sql"select count(*) from test".query[Int]
val logic =
for
count <- transaction(query.selectOne).flatMap(ZIO.fromOption)
_ <- ZIO.logInfo(s"count is $count")
yield ()
override def run = logic.provide(connectionPoolConfig, connectionPool)
App.main(args)
This script will log the failed
message once. However, if you adjust minConnections
to 3 and maxConnections
to 4, the failed
message will be logged 4 times.
I didn't read in details the issue but I fixed something similar some times ago here: https://github.com/zio/zio-jdbc/pull/174
I'm pretty sure #174 was already included when I reported the issue. I mean the issue is still there.
Context
I've noticed a strange behavior which I'm attributing to zio-jdbc but it could actually be caused by ZIO core. I don't know enough of the details to be affirmative here.
Versions
Observed behaviour
When a
Connection
cannot be opened with the database due to a connection timeout for instance (or any other error blocking long enough, in my reproduction scenario it's 30s but on the real case I observed it was 2 minutes), the retry logic seems to be misbehaving and the application retries infinitely instead of crashing.Reproduction scenario
Here's a reproduction test using Scalatest:
When running this test, here's the output:
You can notice that after reaching the 10 retries defined in the retry policy, it starts again to retry back at iteration 0.
Other
If the "long operation" is not that long (1s instead of 30s for instance), the behaviour is not the same: the app crashes as expected after 10 retries.