import structio async def main(n): print(f"[main] Starting sliding timer with timeout {n}") i = structio.clock() with structio.skip_after(2) as scope: while n: # This looks weird, but it allows us to # handle floating point values (basically # if n equals say, 7.5, then this loop will # sleep 7.5 seconds instead of 8), which would # otherwise cause this loop to run forever and # the deadline to shift indefinitely into the # future (because n would never reach zero, getting # immediately negative instead) shift = min(n, 1) print(f"[main] Waiting {shift:.2f} second{'' if shift == 1 else 's'}") await structio.sleep(shift) print(f"[main] Shifting deadline") # Updating the scope's timeout causes # its deadline to shift accordingly! scope.timeout += shift n -= shift print("[main] Deadline shifting complete") # Should take about n seconds to run, because we shift # the deadline of the cancellation n times and wait at most # 1 second after every shift print(f"[main] Exited in {structio.clock() - i:.2f} seconds") structio.run(main, 7.5)