gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 15:10:56 24 4
gpt4 key购买 nike

我有一个主程序,它创建一个 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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com