如何在 Akka 中使用 setReceiveTimeout 同步杀死 child Actor
How to synchronize killing of child Actor using setReceiveTimeout in Akka
背景:
我正在使用 C#,但我认为这个问题也适用于 Java 和 Scala。我有一个大师级演员,通过所有 "Job Messages"。这些作业可以同时执行,只要不共享就不要共享一个"concurrency id"。为了解决这个问题,我为每个 "concurrency id" 生成了一个 child 演员。然后,我使用 setReceiveTimeout 来清理 children 空闲的时候。
我不知道如何在没有竞争条件的情况下做到这一点。以下是一些不起作用的方法:
1) 从 Dictionary 中删除 child,并告诉 child 终止。这是行不通的,因为在触发超时时间和 parent 开始处理消息之前,消息可能已添加到 child 的队列中,导致消息丢失。
2) 从字典中删除child,并发送一个PoisonPill。这不起作用,因为 child 可能会继续处理新工作。如果更多工作达到 parent,parent 将创建一个新的 child,这意味着具有相同并发 ID 的两个事物同时 运行。
3) 从字典中删除 child,并在 "ask" 中删除带有消息的 child。如果消息 returns
parent 是否可以通过任何方式询问 child child 的队列中是否有消息? (这不会是竞争条件,因为发送到 child 的所有消息都来自 parent)
parent 可以检查 child 的队列是否为空,并且 child 是否没有处理任何事情吗?
我是否应该添加一条新消息,如果已完成,"ask" child? (这将是安全的,因为我知道 parent 是唯一发送消息的人,但是如果 child 正在处理一条消息,或者如果调度员池。
我的问题和这个问题类似,不过我是加了"concurrency id"的额外约束,不担心"zombie actors"目前正在关机,只要僵尸有没有工作,也不会得到更多的工作:
Get or create child Akka actor and ensure liveness
Akka 确保 actor 邮箱是私有的。一个演员的邮箱与另一个演员无关。 parent 检查 child 的邮箱是否为空是错误的。
为什么你认为 ask 会阻塞?
一个选择:不杀children。如果您有一组固定的并发 ID,您一遍又一遍地使用,只需让所有参与者保持活动状态即可。 Actor不会消耗太多资源。
另一个选项:
When the parent wants to kill the child:
send a PoisonPill to the child and remove him from the Dictionary.
When the parent receives a "job message" with concurrencyID:
if (Dictionary.contains(concurrencyID) {
send message to child
} else {
if (parent has child with name concurrencyID) {
delay message - for example with scheduler // child is terminating
} else {
create a child with name concurrencyID
send message to child
}
}
背景: 我正在使用 C#,但我认为这个问题也适用于 Java 和 Scala。我有一个大师级演员,通过所有 "Job Messages"。这些作业可以同时执行,只要不共享就不要共享一个"concurrency id"。为了解决这个问题,我为每个 "concurrency id" 生成了一个 child 演员。然后,我使用 setReceiveTimeout 来清理 children 空闲的时候。
我不知道如何在没有竞争条件的情况下做到这一点。以下是一些不起作用的方法: 1) 从 Dictionary 中删除 child,并告诉 child 终止。这是行不通的,因为在触发超时时间和 parent 开始处理消息之前,消息可能已添加到 child 的队列中,导致消息丢失。 2) 从字典中删除child,并发送一个PoisonPill。这不起作用,因为 child 可能会继续处理新工作。如果更多工作达到 parent,parent 将创建一个新的 child,这意味着具有相同并发 ID 的两个事物同时 运行。 3) 从字典中删除 child,并在 "ask" 中删除带有消息的 child。如果消息 returns
parent 是否可以通过任何方式询问 child child 的队列中是否有消息? (这不会是竞争条件,因为发送到 child 的所有消息都来自 parent)
parent 可以检查 child 的队列是否为空,并且 child 是否没有处理任何事情吗?
我是否应该添加一条新消息,如果已完成,"ask" child? (这将是安全的,因为我知道 parent 是唯一发送消息的人,但是如果 child 正在处理一条消息,或者如果调度员池。
我的问题和这个问题类似,不过我是加了"concurrency id"的额外约束,不担心"zombie actors"目前正在关机,只要僵尸有没有工作,也不会得到更多的工作: Get or create child Akka actor and ensure liveness
Akka 确保 actor 邮箱是私有的。一个演员的邮箱与另一个演员无关。 parent 检查 child 的邮箱是否为空是错误的。
为什么你认为 ask 会阻塞?
一个选择:不杀children。如果您有一组固定的并发 ID,您一遍又一遍地使用,只需让所有参与者保持活动状态即可。 Actor不会消耗太多资源。
另一个选项:
When the parent wants to kill the child:
send a PoisonPill to the child and remove him from the Dictionary.
When the parent receives a "job message" with concurrencyID:
if (Dictionary.contains(concurrencyID) {
send message to child
} else {
if (parent has child with name concurrencyID) {
delay message - for example with scheduler // child is terminating
} else {
create a child with name concurrencyID
send message to child
}
}