天天看點

如何停止正在執行的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的動作時同時操作的,這樣又可以節省一部分時間

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