Question

I really feel like I'm doing something that is not possible by design, but I really want to fully understand how Play Iteratees work...

I'm currently writing a function that applies some transformation on an Enumerator through an Enumeratee. As of now, I have no problems doing this specific transformation. But I want to add some elements just before then end of the Enumerator. I thought of using mapInput or mapInputFlatten, since I can see which Input is being processed at the time. My current solution for this problems looks like:

import play.api.libs.iteratee.{Enumerator, Enumeratee, Input, Iteratee}
import scala.concurrent.Await
import scala.concurrent.duration.DurationInt

def appendingEnumeratee: Enumeratee[Int, Int] = Enumeratee.mapInputFlatten {
  case Input.El(i) => Enumerator(i)
  case Input.Empty => Enumerator.enumInput(Input.Empty)
  case Input.EOF => Enumerator(42)
}

Await.result(Enumerator(1 to 41: _*).through(appendingEnumeratee).apply(Iteratee.getChunks), 5.seconds)

However, I end up with java.lang.RuntimeException: diverging iteratee after Input.EOF. This is on Scala 2.10.2 with play-iteratees 2.1.5

Was it helpful?

Solution

I think the problem with your code is the missing EOF. So modifying it to the following will work:

def appendingEnumeratee: Enumeratee[Int, Int] = Enumeratee.mapInputFlatten {
    case Input.El(i) => Enumerator(i)
    case Input.Empty => Enumerator.enumInput(Input.Empty)
    case Input.EOF => Enumerator(42) andThen Enumerator.enumInput(Input.EOF)
}

Or a bit shorter:

def appendingEnumeratee: Enumeratee[Int, Int] = Enumeratee.mapInputFlatten {
    case Input.EOF => Enumerator(42) >>> Enumerator.enumInput(Input.EOF)
    case _else => Enumerator.enumInput(_else)
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top