Question

I'm currently trying to wrap my head around the idea of Enumerators and Iteratees. I decided to start off by looking at Play 2.0's iteratee library, which I've added to my test project with the following lines in my build.sbt file. (I am using Scala 2.10) (docs here)

resolvers += "Typesafe repository" at 
  "http://repo.typesafe.com/typesafe/releases/"

libraryDependencies += "play" %% "play-iteratees" % "2.1.1"

My goal is to create an Enumerator over the bytes of a file, and eventually attach some parsing logic to it, but when I try what appears to be a simple thing, I get an exception. My code looks like this:

val instr = getClass.getResourceAsStream(...)
val streamBytes = for {
  chunk <- Enumerator fromStream instr
  byte <- Enumerator enumerate chunk
} yield byte

val printer = Iteratee.foreach[Byte](println)

streamBytes.apply(printer)

What happens is that (what I assume is) all of the bytes in the file get printed, then I get an IllegalStateException saying that the "Promise already completed".

java.lang.IllegalStateException: Promise already completed.
    at scala.concurrent.Promise$class.complete(Promise.scala:55)
    at scala.concurrent.impl.Promise$DefaultPromise.complete(Promise.scala:58)
    at scala.concurrent.Promise$class.failure(Promise.scala:107)
    at scala.concurrent.impl.Promise$DefaultPromise.failure(Promise.scala:58)
    at scala.concurrent.Future$$anonfun$flatMap$1.liftedTree3$1(Future.scala:283)
    at scala.concurrent.Future$$anonfun$flatMap$1.apply(Future.scala:277)
    at scala.concurrent.Future$$anonfun$flatMap$1.apply(Future.scala:274)
    at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:29)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)

Since the stack trace doesn't point to anywhere in my code, and this is unfamiliar territory, I have no idea what's going wrong. Can anyone offer some insight or a solution to this problem?

Was it helpful?

Solution

See if this works for you. I was getting exceptions with your code too, but when I unwound your for-comp, things worked. I'm not 100% sure why because I thought the for-comp desugared to this code anyway, but I must be missing something:

val bytes = Enumerator fromStream instr flatMap (Enumerator enumerate _)    
val printer = Iteratee.foreach[Byte](b => println(b))    
bytes |>> printer 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top