- 
                Notifications
    You must be signed in to change notification settings 
- Fork 1.4k
Description
TestClock semantics has changed in RC18 in order to fix an issue with Schedules in forked fibers #2677 . I think the new semantics has a different issue. It violates causality and makes it impossible to test certain scenarios, which were testable before RC18. An ideal future version of TestClock would additionally pass the following test:
testM("time should advance when suspended") {
  for {
    now <- clock.currentDateTime
    p1 <- Promise.make[Nothing, Unit]
    p2 <- Promise.make[Nothing, OffsetDateTime]
    _ <- (p1.await *> clock.currentDateTime.orDie.to(p2)).fork
    _ <- TestClock.adjust(1.minute)
    _ <- clock.sleep(1.minute)
    later <- clock.currentDateTime
    _ <- p1.succeed(())
    laterFiber <- p2.await
  } yield assert(now)(isLessThan(later)) && assert(later)(isLessThanEqualTo(laterFiber))
}From the flow of the main fiber we know that time has passed. There is no possible way for the test to succeed, if time does not also advance in the forked fiber. In RC18 TestClock advances fiber time only during sleep. As the forked fiber never sleeps, it is impossible to update the time in the forked fiber. Even if we assume computations to be instantaneous, time should be allowed to pass during suspension due to EffectAsync. This is related to tick as proposed in #3304, but tick alone does not solve it.
I'm not sure what a fix would look like. When a forked fiber suspends due to EffectAsync, its fiber time should be fast forwarded to wall clock time. TestClock would need to know when a forked fiber gets resumed, but that information is not available to TestClock.