Reputation: 13924
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?
Upvotes: 4
Views: 764
Reputation: 35443
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
Upvotes: 1