zio / zio-redis

A ZIO-based redis client
https://zio.github.io/zio-redis
Apache License 2.0
123 stars 63 forks source link

SingleNodeExecutor hangs when Clock service is being used #858

Open almoehi opened 1 year ago

almoehi commented 1 year ago

Hey - I have some code that uses ZIO Clock service. It's a very simple service method which does the following:

When I run tests (which then uses TestClock) and a real Redis container the SingleNodeExecutor hangs indefinitly and it gives me the following warning:

thread=#zio-fiber-236 message="Warning: A test is using time, but is not advancing the test clock, which may result in the test hanging. Use TestClock.adjust to manually advance the time." location=zio.redis.SingleNodeExecutor.run file=SingleNodeExecutor.scala line=40

Relevant method from TokenService service:

  def create(lifetime: Option[zio.Duration], refId: Option[String]): IO[TokenStoreError, Token] = (for {
    nowNanos <- Clock.currentTime(TimeUnit.NANOSECONDS)
    token <- generate()
    maybeSuffix = refId.map("." + _).getOrElse("")
    _ <- (lifetime match {
      case Some(Duration.Infinity) => redis.set(Token.unwrap(token) + maybeSuffix, 0, None)
      case Some(Duration.Zero) => ZIO.succeed(true)
      case Some(finite) => redis.set(Token.unwrap(token) + maybeSuffix, (nowNanos + finite.toNanos), Some(finite))
      case None => ZIO.succeed(true)
    })
  } yield token)
    .logError(s"Failed to create new Token with lifetime $lifetime and refId $refId")
    .mapError(e => TokenStoreError.TokenCreationFailed(e.getMessage))

code in zio-test spec (that test should fail):

      test("Token expiration") {
        for {
          fibre <- TokenStore.create(Some(Duration.fromMillis(200))).fork
          _ <- TestClock.adjust(1.minute)
          token <- fibre.join
          _ <- TokenStore.verify(token)
        } yield assertTrue(token.length > 0)
      }
mijicd commented 1 year ago

Sorry for the (very) delayed response. I don't think that running the tests against the "real" Redis with a test clock will work.