lampepfl / gears

A strawman for a low-level async library in Scala 3.
https://lampepfl.github.io/gears/
Apache License 2.0
247 stars 24 forks source link

Introduce `Retry` as an alternative to Tasks #48

Closed natsukagami closed 6 months ago

natsukagami commented 6 months ago

What is this?

This PR proposes a new API for handling retries and timeouts.

The Task abstraction

The Task abstraction represents "Future templates", or, referential transparent wrappers around asynchronous code that can be turned into a Future by running them. While this is from a theoretical stand-point a good feature to include, when using gears I find them not very useful as-is, since the alternative of just directly using Async ?=> T function types is both more straightforward and easier to compose.

Tasks however provide a good story about managing asynchronous tasks, which includes running them with timeouts and a retry policy (including exponential back-offs, attempt counting etc.). Unfortunately I don't think the API presented by Task currently is very nice at doing so:

The Retry API

In contrast, the Retry API provides up-front declaration of the retrying policy, and lets the user specify the operation at the last moment:

class Retry:
    def apply[T](body: => T)(using Async): T // blocking, runs `body` with the configured Retry policy

while allowing the user to build up the Retry policy by method chaining:

Retry
  .untilSuccess
  .withMaximumFailures(5)
  .withDelay(Delay.backoff(starting = 5.millis, maximum = 1.second)):
     // the operation

This API intentionally does not deal with encapsulating async operations in any way: the call is supposed to be blocking, so it is safe to capture the enclosing Async instance.

Currently Retry supports:

Sidenote: withTimeout

This PR also adds a simple withTimeout function that runs an asynchronous operation with a given timeout. This can be manually implemented by running the operation in a Future and racing it a Timer (or another sleeping future), however I think this is a worthy addition to the standard operations, and will probably need some support once #46 lands.

Progress