热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

akka系统中停止运行任务的问题

  上周的工作中遇到了一个停止运行任务时的问题,就是在一个任务运行到一半时需要停止的问题。正常的需求是一按停止按钮,就要立即

   上周的工作中遇到了一个停止运行任务时的问题,就是在一个任务运行到一半时需要停止的问题。正常的需求是一按停止按钮,就要立即停止,但现在都要等程序运行完才能停止,现在是一个bug。由于之前写任务运行逻辑的不是我,因此我先花一个小时苦读大神们的代码,了解了他们对于任务运行那块的逻辑,发现是首先前端发消息给一个Actor,然后这个Actor用actorOf方法创建许多子Actor,然后再对这些Actor调用ActorSelection创建运行这个任务的Actor。

   之前以为通过获取Actor的地址,终止这个Actor,然后自动终止其所有子Actor应该就能停止任务了,后来发现根本停不下来。

   第一次尝试是在状态机FSM中不仅在whenUnhandled方式下停止Actor,而且在其他每一种状态下都调用停止Actor操作,直接终止运行该线程的Actor。

   这里顺便普及一下停止Actor的时候,是给该Actor发送两种消息,Kill或者PoisonPill。使用Kill消息可以在不损失缓冲区中消息的情况下重启Actor对象,但是不会停止Actor对象,仅仅是重启,而且会抛出异常,使用PoisonPill消息可以停止Actor对象,但允许Actor对象处理完收到PoisonPill消息之前存储在缓冲区中的消息。然后我又尝试了context.stop(actorRef)去直接停止某Actor,同样无济于事,线程依旧潇洒地运行结束。

   这个时候我发现问题应该转移到线程级别,既然终止Actor是不起作用的,我就干脆把这个线程终止掉。一开始我们采用给运行线程的Actor发送消息的方式终止该线程,发现能停止,但还是在任务运行完之后停止。后来我意识到,Actor处理消息应该是按照发送顺序来的,首先发送的消息是处理这个任务,所以只有处理完任务才会处理停止线程这个消息,此时线程已经不是运行状态了。因此我干脆定义了一个线程安全的HashMap,保存了id和Process对象的映射关系,可以通过这个数据结构搜索到线程对象,当父Actor收到终止任务命令时,不再向运行该任务的子Actor发送消息,而是在父Actor中直接调用运行任务的线程的Process对象里的destroy方法,直接终止这个线程,终于成功了。

   得出结论就是,akka系统对于线程粒度的启停控制可能还是有一定缺陷,需要我们根据线程的Process对象自己来做停止操作。


推荐阅读
author-avatar
宇剑小窝_911
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有