前面學習了graph的基本概念,參數設置,特殊節點和邊,今天學習一下檢查點
檢查點可能名稱比較抽象,換個名字可能比較容易理解,進度保存點或者存檔點,可以類比游戲中保存當前游戲進度的存檔進度
主要用于人工介入的場景,大概流程是每個節點后保存檢查點,在某些節點前或后中斷,進行人工操作,操作完成后,調用恢復接口resume,graph接收用戶輸入并根據最近的檢查點(存檔)恢復執行
可以將其分為存檔進度,存檔執行流程和存檔執行器來了解?
存檔進度
CheckPoint 類就好比被保存的存檔,類中包含一個id(默認自動生成一個uuid),當前節點id nodeId,下一節點id nextNodeId,全局狀態 Map<String, Object> state,用后三個字段來記錄當前圖的執行狀態。
存檔執行流程
graph會在開始節點記錄初始檢查點,并且在每個節點執行完畢后更新全局狀態時保存檢查點,
在中斷或異常后,通過調用resume接口來恢復現場,需要再resume接口的RunnableConfig參數中設置checkPointId
每個會話有自己的threadId,不同threadId的檢查點會分開管理,確保可以按不同會話來恢復進度
存檔器
簡單樣例
StateGraph graph = ...CompileConfig compileConfig = CompileConfig.builder()
.saverConfig(SaverConfig.builder().type(SaverConstant.FILE).register(SaverConstant.FILE, saver).build()).build();CompiledGraph app = graph.compile(compileConfig);
存檔器的設置
在前面參數設置章節有提到過,主要是在編譯圖時通過CompileConfig設置
CompileConfig 中包含 SaverConfig
SaverConfig中包含一個Map<String, BaseCheckpointSaver>類型的savers屬性
SaverConfig提供一個register方法來注冊存檔器,注冊的存檔器會放到savers中
SaverConfig還包含一個String類型的type字段
當調用SaverConfig的無參get方法時,取savers.get(type),即savers中key為type對應值的存檔器,所以type可以理解為默認存檔器的key
存檔器的實現類
MemorySaver:基于內存的存檔器,斷電后存檔消失
FileSystemSaver:基于文件系統的存檔器
MongoSaver:基于mongodb的存檔器
RedisSaver:基于redis的存檔器
VersionedMemorySaver:帶版本的內存存檔器,適合一個會話多次執行圖的情況,每次在圖的結束節點會將檢查點移入歷史版本
存檔器內部工作原理
以MemorySaver為例了解一下Saver的內部工作原理
MemorySaver內部包含一個 Map<String, LinkedList<Checkpoint>> 類型的屬性,key為threadId,值為每個節點后保存的檢查點
MemorySaver實現了BaseCheckpointSaver接口,提供get、put、list、clear、release、getLast等方法
調用 put 方法時若 RunnableConfig 的 checkPointId 為空,則直接存入當前檢查點,并更新 RunnableConfig 中的 checkPointId;若非空,則替換相同checkPointId的檢查點(實際由于更新后的RunnableConfig被丟棄,所以checkPointId一直都是空)
調用 get 方法時若?RunnableConfig 的 checkPointId 為空,則取鏈表中第一條記錄(最新記錄);若不為空,則取對應id的 CheckPoint?