Search code examples
scalaakkaakka-stream

What is the Use Case of `extrapolate` in `Akka-Streams`?


I just tried conflate and extrapolate in akka-streams.

As conflate makes totally sense to me, I don't get the Use Case of extrapolate.

Why should we add more work for the downstream - when the upstream does not demand it?

From the Scala Doc:

Allows a faster downstream to progress independent of a slower upstream.


Solution

  • For one example:

    Game development

    In video games, it's common to have at least two "loops": a logic/game loop and a rendering loop. Usually, the rate of the game loop (the "tick rate") is slower than the rate of the rendering loop (the "frame rate"). For example, a logic tick might occur 10 times a second, but the frame rate should usually be at least 60 frames per second. In order for there to be something to render in between ticks, game developers use either extrapolation or interpolation. As you might have guessed, the extrapolate function is well suited for extrapolation. Here's an example with a tick rate of 10 ticks per second and no frame rate limit:

    Source.tick(0.millis, 100.millis, 0)
        .scan(intialGameState) { (g, _) => tick(g) }
        .extrapolate(extrapolateFn)
        .runForeach(render)
    

    Now extrapolateFn just needs to return an iterator that provides extrapolated game states on demand:

    def extrapolateFn(g: GameState) = Iterator.continually {
      // Compute how long it has been since `g` was created
      // Advance the state by that amount of time
      // Return the new state
    }