Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala Play `Enumerators`: push or pull?

I'm really having trouble understanding the fundamental purposes for Play's Iteratees and Enumerators.

I've read

  • Understand Play2 Iteratees for Normal Humans
  • Iteratees
  • Enumerators

I read this answer to find that instead of relying on a pulling model, like InputStream, it uses a pushing model.

Iteratees are an interesting beast -- on one hand, it "pushes" data to the handler, instead of relying to the handler to pull data, and, therefore, has better performance. On the other hand, it allows the handler to control when the flow should be stopped.

But then Play's documentation on Iteratees says

Or more generally enumerating a java.io.InputStream using Enumerator.fromStream. It is important to note that input won’t be read until the iteratee this Enumerator is applied on is ready to take more input.

Wait....so what is going on?

Does the data get pushed by the Enumerator or pulled by the Iteratee? (i.e. who decides when it is time to calculate more data)

like image 752
Paul Draper Avatar asked Dec 05 '25 04:12

Paul Draper


1 Answers

Both. It is entirely non-blocking for both ends of the stream.

The Enumerator doesn't push any data until the Iteratee is ready to receive it, and it doesn't push any more data until the Iteratee signals it is ready for more. At the same time, the Enumerator can take as long as it wants to push data. Neither process will block on the other.

This method, on Iteratee, is critical to understanding how it works:

abstract def fold[B](folder: (Step[E, A]) ⇒ Future[B])(implicit ec: ExecutionContext): Future[B]

This is the sole abstract method in Iteratee, the only one that must be implemented. All the rest of the methods are defined in terms of fold. When an Enumerator is applied to an Iteratee, it invokes this method, providing the folder which is effectively a callback. Once the Iteratee is ready, it invokes folder providing the state it is currently in, Cont if it can receive more data, Done if it doesn't need any more, or Error if something has gone wrong. And because folder returns a Future, it can take as long as it needs to provide further input if the Iteratee is in the Cont state.

like image 136
wingedsubmariner Avatar answered Dec 09 '25 06:12

wingedsubmariner



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!