Reactive Messaging Patterns with Actor Model — 3 Akka Actor (二)生命週期管理

Reactive Messaging Patterns with Actor Model — 3 Akka Actor (二)生命週期管理_第1张图片
Official Actor Status machine

Akka Actor 的生命週期,正如同一個狀態機一樣,經由幾個Trigger(method invoke)去進行狀態轉換。

上圖是Akka官方提供的狀態機,不過我從實務的代碼來看運行的狀態改動會更貼切一點:

Actor 在運行時,Akka framework在對於Actor被初始化時會引發兩個CallBack

preStart()

postStop()

由於Akka 已經有提供了基類(base abstract class)的template pattern 提供基礎的運行代碼,所以我Override 這兩個method:

Reactive Messaging Patterns with Actor Model — 3 Akka Actor (二)生命週期管理_第2张图片
Override preStart() , postStop() callBack methods

在初始化Actor 的時候,我們不能很單純的把它當成物件直接去new ,原因是Actor 是仰賴於整個Akka framework 做生命週期管控,Akka提供了 ActorRef 機制(你可以想像他是actor instance access interface),透過ActorRef 對instance 做查找與執行訊息傳遞的行為 !

這樣的基礎限制條件,其實跟很多知名的容器體系下的元件使用模式理念相同,譬如我們不能直接去New EJB Instance,不能直接去New一個已經有對Spring framework 重度相依的 Bean instance一樣。


Try new instance by new syntax but would be error.

上例當中直接new ,執行結果如下:

akka.actor.ActorInitializationException: You cannot create an instance of [solid.humank.actor.ExplainActorLifeCycle] explicitly using the constructor (new). You have to use one of the ‘actorOf’ factory methods to create a new actor. See the documentation.

這是因為Akka framework 是以factory pattern(by actorOf method)來統一實現Actor 初始化的做法,正確的作法應該是利用Akka system context去創建你需要的Actor instance。

Reactive Messaging Patterns with Actor Model — 3 Akka Actor (二)生命週期管理_第3张图片
Akka create actor with akka system context

執行啟動後,可以看到一個類似於Web URI 的位址連結


Callback invoked

[akka://sample/user/test]

Akka 對於Actor 的管理模式,是採行一個樹狀的地址模型,每一個actor 都能創建出他的子Actor 或相關連操作的 Actor,每一個上層的Actor都有責任與義務去照顧與監控他底下的子Actor或相依的Actor,這樣的樹狀體系體現在URI上,就還蠻容易理解了。

從上述的log當中確實看到,Actor 物件在初始化之後,會自動地進行preStart()/postStop(),為了能更精確理解建構的流程,我刻意添加了default constructor 來看看他跑的流程:

run with constructor

如果在對Actor 的操作,有一些很特定的業務場景需要綁定相依的物件資源時(譬如建構子直接注入 external repository, 或者注入 external service gateway access point),可以在這幾個method 當中特別去留意狀態變化,有時候問題有機會在這幾個時機點去幫忙做除錯的檢驗。

接著看看如何停止Actor : 

Akka 在Java 方面的實現是透過 Actor receive command時, 基於 actorContext 停止Actor


Reactive Messaging Patterns with Actor Model — 3 Akka Actor (二)生命週期管理_第4张图片
Stop Actor via actorContext

寫個測試代碼運行看看

Reactive Messaging Patterns with Actor Model — 3 Akka Actor (二)生命週期管理_第5张图片
demo stop Actor in Junit

運行結果

Reactive Messaging Patterns with Actor Model — 3 Akka Actor (二)生命週期管理_第6张图片
testing result

可以看到Actor實體確實正確的被停止了,但是因為我試圖要做驗證檢查Actor status,Akka framewok抗議了,因為我試圖要從ActorSystem 當中去獲取還在運行狀態的Actor,但是因為已經中斷了(不存在這樣的一個running actor),所以會拋出illegalActorStateException。

特別一提,Akka 在Java 的實現上,僅提供了透過receive command ,藉由actorContext 執行stop actor 的做法,但是在Scala上,則可以直接在外部操作Stop 的這個trait method直接停掉Actor,這是蠻大的差異的。


Reactive Messaging Patterns with Actor Model — 3 Akka Actor (二)生命週期管理_第7张图片
Actor lifecycle trait method define

上圖中,很明確地看到了Akka 的設計原則是只能夠透過內部context來操作生命週期轉換,不過希望只是我還沒找到在Java上的外部停止Actor的做法,不然只能基於Command 的操作還真是有些不方便。

前面測試理解到假設Actor Instance已經是進入到terminated的狀態,若我們試圖再一次對他送信息,看看系統會有啥反應?

Reactive Messaging Patterns with Actor Model — 3 Akka Actor (二)生命週期管理_第8张图片
reSendMessageToAnTerminatedActor

ActorSystem偵測到這個actor的狀態已經是不可觸及的,於是把信息塞入到DeadLetter 裡頭去 !


Reactive Messaging Patterns with Actor Model — 3 Akka Actor (二)生命週期管理_第9张图片
DeadLetter environment

接續,就是該思考怎麼把Dead Letter 給拿出來做後續處理了~待續!

你可能感兴趣的:(Reactive Messaging Patterns with Actor Model — 3 Akka Actor (二)生命週期管理)