在本文中,您將瞭解立即和延遲確認之間的差異。
立即確認
對於許多應用程式,您想要確保事件能即時被確認。 這可防止持久化版本落後於記憶體中的當前版本,並避免在單元失效時遺失最新狀態的風險。 您可以遵循下列規則來保證這一點:
- 在 grain 方法返回之前使用RaiseEvent來確認所有ConfirmEvents的呼叫。
- 在粒紋方法傳回之前,請確定完成所 RaiseConditionalEvent 傳回的工作。
- 避免使用 ReentrantAttribute 或 AlwaysInterleaveAttribute 屬性,以便於任何時間點只處理一次 Grain 呼叫。
如果您遵循這些規則,表示在引發事件之後,在事件寫入儲存之前,無法執行其他 Grain 程式碼。 因此,無法觀察記憶體內部版本與預存版本之間的不一致。 雖然這通常是您想要的,但它也有一些潛在的缺點。
潛在缺點
如果與遠端叢集或儲存的連線暫時中斷,則資料粒子將會無法使用。 實際上,粒紋無法在等候確認事件時執行任何程序代碼,這可能需要無限時間(記錄一致性通訊協定會持續重試,直到還原記憶體連線為止)。
處理單一 grain 單元的多次更新時,每次確認一個更新可能會變得非常低效,這可能導致吞吐量不佳。
延遲確認
若要改善上述情況的可用性和輸送量,穀物可以選擇執行下列其中一項或兩項作業:
- 允許粒度方法在無需等待確認即可引發事件。
- 允許重新進入,因此即使先前的呼叫停滯等待確認,系統粒子仍可繼續處理新的呼叫。
這表示在某些事件尚未完全確認的情況下,程式碼仍可以執行。 JournaledGrain<TGrainState,TEventBase> API 有特定的規定,可讓您精確控制如何處理目前進行中的未確認事件。
您可以檢查下列屬性,以找出目前未確認的事件:
IEnumerable<EventType> UnconfirmedEvents { get; }
此外,由於JournaledGrain<TGrainState,TEventBase>.State屬性返回的狀態不包含未確認事件的效果,因此存在替代屬性:
StateType TentativeState { get; }
這個屬性會傳回從 State
取得並套用所有未確認事件的「暫定」狀態。 暫定狀態基本上是一個「最有可能的估計」,在核實所有未確認的事件之後,可能會成為下一個確認狀態。 不過,不保證它實際上會變成已確認的狀態。 這是因為穀物可能會失敗,或事件可能會與其他事件競爭並失敗,導致它們被取消(如果有條件)或出現在序列中比預期更晚(如果無條件)。
並行保證
請注意,Orleans 回合式排程(合作式並行)始終保證適用,即使使用重新進入或延遲確認的情況下也是如此。 這表示即使有數種方法正在進行中,只有一種方法可以主動執行,但所有其他方法都卡在 await
。 因此,平行線程永遠不會造成任何真正的競爭。
特別是請注意:
- 屬性 State、 TentativeState、 Version和 UnconfirmedEvents 可以在方法執行期間變更。
- 不過,這類變更只能在停滯於
await
時發生。
這些保證假設您的程式碼會符合有關工作和 async/await 的建議做法 中(特別是,不使用執行緒池工作,或只將它們用於不會呼叫 Grain 功能且已正確等待的程式碼)。