Search code examples
scalascalatestzio

Scala - differents between eventually timeout and Thread.sleep()


I have some async (ZIO) code, which I need to test. If I create a testing part using Thread.sleep() it works fine and I always get response:

for {
 saved <- database.save(smth)
 result <- eventually {
   Thread.sleep(20000)
   database.search(...) 
 }
} yield result

But if I made same logic using timeout and interval from eventually then it never works correctly ( I got timeouts):

for {
   saved <- database.save(smth)
   result <- eventually(timeout(Span(20, Seconds)), interval(Span(20, Seconds))) {
     database.search(...) 
   }
} yield result

I do not understand why timeout and interval works different then Thread.sleep. It should be doing exactly same thing. Can someone explain it to me and tell how I should change this code to do not need to use Thread.sleep()?


Solution

  • Assuming database.search(...) returns ZIO[] object.

    eventually{database.search(...)} most probably succeeds immediately after the first try.

    It successfully created a task to query the database. Then database is queried without any retry logic.

    Regarding how to make it work:

    val search: ZIO[Any, Throwable, String] = ???
    val retried: ZIO[Any with Clock, Throwable, Option[String]] = search.retry(Schedule.spaced(Duration.fromMillis(1000))).timeout(Duration.fromMillis(20000))
    

    Something like that should work. But I believe that more elegant solutions exist.