scala - 终止 Actor 和 ActorSystem 后应用程序未退出

标签 scala akka

我有一个主程序,它创建一个 ActorSystem,一个 Actor 并向 Actor 发送一些消息。处理消息后,我发送 PoisonPill 来杀死 Actor。然后我关闭了 Actor 系统。

在 Actor 中,我正在调用 Await 以等待 future 完成。我面临的问题是,即使actor 被PoisonPill 终止并且ActorSystem 关闭,应用程序也没有退出。

def main(args: Array[String]): Unit = {

    val actorSystem = ActorSystem("sytem")
    val creationActor = actorSystem.actorOf(Props[MyActor], "MyActor")
    ...
    creationActor ! Message    //may be called multiple times
    creationActor ! PoisonPill
    ...
}

而 Actor 代码是
class MyActor extends Actor {

  override def receive: Receive = {
    case Message => {
       ...
      Await.result(Dataset.create(datasetId), 30 seconds) 
      //Dataset.create returns a Future. Also this method uses an
      //ExecutionContext of its own.
      ...
    }
  }

  override def postStop() = {
    context.system.shutdown()
  }
}

如果我注释掉 Await.result 部分,程序就会退出。

编辑:
看起来我已经找到了根本原因。

Dataset.create(...) 中使用的 ExecutionContext 是罪魁祸首。当我使用不使用 Futures 的同步版本的 Dataset.create(...) 时,我的应用程序退出。

Dataset.create() 使用的 ec 是这样定义的implicit val defaultContext = ExecutionContext.fromExecutorService(Executors.newFixedThreadPool(100))
仍然很想知道为什么异步版本不退出应用程序。

编辑 2:
如果我将 Await 部分更改为
val future = BQDataset.create(datasetId)
future onComplete {
  case Success(d) => ...
  case Failure(e) => ...
}

我仍然面临同样的问题。
正如@cem-catikkas 提到的,当我调用 BQDataset.create 时创建的 ExecutionContext正在闲逛。我通过使用 jstack 验证了这一点,可以看到 "pool-1-thread-1" prio=5 tid=0x00007ff49aa1e800 nid=0x4e03 waiting

最佳答案

当我打电话时Dataset.create(…) ,该方法创建一个 ExecutionContext并使用它来执行第三方库。这个第三方库打开了一个网络连接,但它没有正确的 shutdown()close()清除底层连接的方法。

正因为如此,即使我打电话ExecutionContext.shutdown() ,它无法关闭线程池。这就是应用程序没有退出的原因。

关于scala - 终止 Actor 和 ActorSystem 后应用程序未退出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27834200/

相关文章:

jenkins 上的 scala 代码覆盖工具 Cobertura

scala - 不同类型任务的功能组合 - Scala

java - Akka future 指导

scala - 在集群节点上运行的 Akka Streams

scala - 如何在 Scala 中访问类的类型参数

javascript - Scalatags 生成 HTML 还是 Javascript?

scala - Spray/Akka 缺失隐式

scala - 使用 Akka 将文件从服务器流式传输到客户端

scala - 尝试从 akka 类型应用程序内部创建一个经典的 actor

scala - 从 playframework 2.0 向网络服务发出 GET 请求