Why does Play PushEnumerator need to close () before the iterator completes?

The following example adapted from the Play Framework documentation:

val enumerateUsers: Enumerator[String] = {
  Enumerator("Guillaume", "Sadek", "Peter", "Erwan")
}
val consumeOne = Cont[String, String](in =>
  in match {
    case Input.EOF =>
      Done("", Input.Empty)
    case Input.Empty =>
      Done("", Input.Empty)
    case Input.El(s) =>
      Done(s, Input.Empty)
  })
println((enumerateUsers |>> consumeOne).flatMap(_.run).await.get)

displays Guillaume.

However, if I change it so that it Enumeratorwas PushEnumerator:

val enumerateUsers: PushEnumerator[String] = Enumerator.imperative[String]()
// consumeOne as before
val i = enumerateUsers |>> consumeOne
enumerateUsers.push("Guillaume")
enumerateUsers.push("Sadek")
enumerateUsers.push("Peter")
enumerateUsers.push("Erwan")
println(i.flatMap(_.run).await.get)
// Timeout exception

I get a timeout exception on an iteration promise.

To get him to do the same as before, I need to close PushEnumerator.

val enumerateUsers: PushEnumerator[String] = Enumerator.imperative[String]()
// consumeOne as before
val i = enumerateUsers |>> consumeOne
enumerateUsers.push("Guillaume")
enumerateUsers.push("Sadek")
enumerateUsers.push("Peter")
enumerateUsers.push("Erwan")
enumerateUsers.close() // <-- magic line
println(i.flatMap(_.run).await.get)

And it prints Guillaumeas before.

I can not find a document that will tell me why, or what is the semantic difference here. Can someone point the way?

. . :) @huynhjl , , , . Play , - , ( : D). play.core.server.netty.Helpers , socketOut[A](...). socketOut[A](...) , step, Iteratee. Iteratee e , El(e). , Iteratees , , , , , ... :)

+3
1

Enumerator , iteratee , iteratee, iteratee. close() , , iteratee . , , . , , :

val i = enumerateUsers |>> consumeOne
i.flatMap(_.run).onRedeem(println) // we will have a result we want to print
// now feed some data
enumerateUsers.push("Guillaume")
enumerateUsers.push("Sadek")
enumerateUsers.push("Peter")
enumerateUsers.push("Erwan")
// no more input, trigger promise computation
enumerateUsers.close() 

, enumerateUsers , , ( ).

+2

All Articles