【问题标题】:Play Iteratees: error for simple file iterationPlay Iteratees:简单文件迭代的错误
【发布时间】:2013-05-27 07:06:32
【问题描述】:

我目前正试图围绕EnumeratorsIteratees 的想法。我决定从查看 Play 2.0 的 iteratee 库开始,该库已添加到我的测试项目中,并在我的 build.sbt 文件中添加了以下行。 (我使用的是 Scala 2.10)(docs here)

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

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

我的目标是在文件的字节上创建一个枚举器,并最终为其附加一些解析逻辑,但是当我尝试看似简单的事情时,我得到了一个异常。 我的代码如下所示:

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)

发生的情况是(我假设是)文件中的所有字节都被打印出来,然后我收到一个 IllegalStateException 说“承诺已经完成”。

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)

由于堆栈跟踪没有指向我的代码中的任何地方,而且这是一个不熟悉的领域,我不知道出了什么问题。谁能提供一些见解或解决此问题的方法?

【问题讨论】:

    标签: scala playframework-2.0 iterate


    【解决方案1】:

    看看这是否适合你。我的代码也出现了异常,但是当我解开你的 for-comp 时,一切正常。我不是 100% 确定为什么,因为我认为 for-comp 无论如何都与此代码脱糖,但我一定遗漏了一些东西:

    val bytes = Enumerator fromStream instr flatMap (Enumerator enumerate _)    
    val printer = Iteratee.foreach[Byte](b => println(b))    
    bytes |>> printer 
    

    【讨论】:

    • 这很奇怪......我再次尝试了同样的事情(这次在工作中),但它不是异常,而是在打印完成后永远挂起。即使使用您提供的代码,它也会挂起。我将不得不稍后再试一次(下班后),然后回复你。
    • 我休息了一段时间,发现我最近的尝试挂了,因为有一个内部 ExecutionContext 正在使用,而不是我真正想要的,它正在创建非守护线程.这似乎是 Play 中的一个错误,不是吗?
    • 同意。 enumerate 需要隐含的 ExecutionContext。当我给它一个然后在打印完成后关闭该上下文时,我的服务器仍然保持运行状态,这不是我所期望的。当然值得进一步调查。如果在jconsole中拉起来,可以看到一个叫iteratee-execution-context的线程池。
    • 看起来它正在开发中:github.com/playframework/Play20/issues/807 我只会将此答案标记为已接受,因为它会带来一些有用的信息。
    猜你喜欢
    • 2017-03-24
    • 1970-01-01
    • 2012-08-08
    • 2011-05-25
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-16
    相关资源
    最近更新 更多