如何停止正在执行的Actor

正如标题所说的,这篇帖子主要说下,在解决这个问题的时候所遇到的问题

先说下背景:

1,一个请求,启动多个actor去执行任务,当任务执行过程中,又请求的一次,进行了重复请求

这种情况下,会出现异常InvalidActorNameException,也就是说actor的名字重复了

首先想到将正在执行的actor关闭,actor的关闭我这里说一种,actorSysm.stop(actor);

actorSystem类型是ActorSystem,如果不知道这个是怎么来的,去搜索下怎么创建actor,自然就有了

但是这里有个问题,stop的命令不会立即终止actor,不像linux的kill一样,直接杀死,而是要发送让其

死亡的消息,但是我们不可能等到这个actor彻底死了,才去创建新的actor

这期间试了几种方法,都不能满足需求

最后,只能曲线救国

那就是每次请求进来,重新建立actorSystem

ActorSystem systemo = system.apply("AkkaVehicleReport");

然后将之前的actorSystem关闭

system.shutdown();

最后将之前的actorSystem的引用指向新建的actorSystem

system = systemo;

这样做的效果就是每次都是新的actorSystem去创建actor执行任务,不会出现名字重复的问题

同时关闭了之前的actorSystem,之前创建的actor会逐层被杀死,解决了不会因为重复提交而造成

一直创建actor的问题,

因为我的actor执行的完成之后会将数据保存到一个地方,这么操作还有一个意外收获

那就是之前的actor未被杀死之前执行完的数据会被保存下来,新建的actor不需要再次执行

提高了数据利用率

下面把相对完整的代码贴出来,欢迎大家指导

注入部分:

@Autowired

private ActorSystem system;

这里说下,如果你无法注入这个actorSystem,需要增加一部分代码,这里不做解释,可以自己搜下,找不到可以找我-469798404

方法内部:

ActorSystem systemo = system.apply("AkkaVehicleReport");

system.shutdown();

system = systemo;

for (int i = 1; i <= 20; i++) {
			ReportMessage msg = new ReportMessage();
			String actorName = session.getId() + "pageActor" + i;
			try {
				actorList.add(actorName);
				ActorRef pageActor = system.actorOf(SpringExtProvider.get(system).props(PageActor.class), actorName);
				System.out.println("---" + actorName + "-----------create");
				pageActor.tell(msg, ActorRef.noSender());
			} catch (InvalidActorNameException e) {
				e.printStackTrace();
			}
		}

 创建了20个actor,去执行任务

 @Override
	public void onReceive(Object msg) throws Exception {
		
		if(msg instanceof ReportMessage){
			//查询数据,处理数据
			ReportMessage remsg = (ReportMessage)msg;
			//判断该部分数据是否处理完成
			if(//处理完成){
				System.out.println("----------重复---done---" + this.self().path().name());
			}else{//未处理完成
				//重新处理
				System.out.println("-------------done---" + this.self().path().name());
			}
			getContext().stop(this.getSelf());
		}
		else{
			unhandled(msg);
		}
		
	}

 整体的结构就是这样,删掉了一些业务代码

整体思路就是这样

重复提交时,创建actor的动作和停止正在执行的actor的动作时同时操作的,这样又可以节省一部分时间

只是可能要多消耗一些性能

猜你喜欢

转载自fox-mt.iteye.com/blog/2256661
今日推荐