粒紋生命週期概觀
Orleans 粒紋使用可觀察的生命週期 (請參閱 Orleans 生命週期),以有序地進行啟用和停用。 這可讓粒紋邏輯、系統元件和應用程式邏輯在粒紋啟用和收集期間能夠有序地啟用和停止。
階段
預先定義的粒紋生命週期階段如下。
public static class GrainLifecycleStage
{
public const int First = int.MinValue;
public const int SetupState = 1_000;
public const int Activate = 2_000;
public const int Last = int.MaxValue;
}
First
:粒紋生命週期中的第一個階段。SetupState
:在啟用前設定粒紋狀態。 對於具狀態的粒紋,這是當 IStorage.RecordExists 為true
時,從儲存體載入 IStorage<TState>.State 的階段。Activate
:呼叫 Grain.OnActivateAsync 和 Grain.OnDeactivateAsync 的階段。Last
:粒紋生命週期中的最後一個階段。
雖然粒紋生命週期將在粒紋啟用期間使用,但由於粒紋在某些錯誤情況下不會一律停用 (例如定址接收器損毀),應用程式不應認定粒紋生命週期必定會在粒紋停用期間執行。
粒紋生命週期參與
應用程式邏輯可透過兩種方式參與粒紋的生命週期:
- 粒紋可參與其生命週期。
- 元件可透過粒紋啟用內容來存取生命週期 (請參閱 IGrainContext.ObservableLifecycle)。
- 粒紋可參與其生命週期。
- 元件可透過粒紋啟用內容來存取生命週期 (請參閱 IGrainActivationContext.ObservableLifecycle)。
粒紋一律會參與其生命週期,因此可以藉由覆寫參與方法來導入應用程式邏輯。
範例參與
public override void Participate(IGrainLifecycle lifecycle)
{
base.Participate(lifecycle);
lifecycle.Subscribe(
this.GetType().FullName,
GrainLifecycleStage.SetupState,
OnSetupState);
}
在上述範例中,Grain<TGrainState> 會覆寫 Grain.Participate 方法,以指示生命週期在其 GrainLifecycleStage.SetupState 階段呼叫 OnSetupState
方法。
在粒紋建構期間建立的元件也可以參與生命週期,而不需要新增任何特殊粒紋邏輯。 由於粒紋的內容 (IGrainContext) (包括粒紋的生命週期 IGrainContext.ObservableLifecycle) 是在粒紋建立之前建立的,任何由容器插入粒紋中的元件都可以參與粒紋的生命週期。
在粒紋建構期間建立的元件也可以參與生命週期,而不需要新增任何特殊粒紋邏輯。 由於粒紋的啟用內容 (IGrainActivationContext) (包括粒紋的生命週期 IGrainActivationContext.ObservableLifecycle) 是在粒紋建立之前建立的,任何由容器插入粒紋中的元件都可以參與粒紋的生命週期。
範例參與、建立和啟用
下列元件會在使用其 Factory 函式 Create(...)
建立時,參與粒紋的生命週期。 此邏輯可能存在於元件的建構函式中,但其風險為元件可能會在完成建構之前新增至生命週期,這樣可能不安全。
public class MyComponent : ILifecycleParticipant<IGrainLifecycle>
{
public static MyComponent Create(IGrainContext context)
{
var component = new MyComponent();
component.Participate(context.ObservableLifecycle);
return component;
}
public void Participate(IGrainLifecycle lifecycle)
{
lifecycle.Subscribe<MyComponent>(GrainLifecycleStage.Activate, OnActivate);
}
private Task OnActivate(CancellationToken ct)
{
// Do stuff
}
}
public class MyComponent : ILifecycleParticipant<IGrainLifecycle>
{
public static MyComponent Create(IGrainActivationContext context)
{
var component = new MyComponent();
component.Participate(context.ObservableLifecycle);
return component;
}
public void Participate(IGrainLifecycle lifecycle)
{
lifecycle.Subscribe<MyComponent>(GrainLifecycleStage.Activate, OnActivate);
}
private Task OnActivate(CancellationToken ct)
{
// Do stuff
}
}
使用 Create(...)
Factory 函式在服務容器中註冊範例元件後,任何以元件建構為相依性的粒紋都會讓元件參與其生命週期,而無須在粒紋中使用任何特殊邏輯。
在容器中註冊元件
services.AddTransient<MyComponent>(sp =>
MyComponent.Create(sp.GetRequiredService<IGrainContext>());
services.AddTransient<MyComponent>(sp =>
MyComponent.Create(sp.GetRequiredService<IGrainActivationContext>());
以元件作為相依性的粒紋
public class MyGrain : Grain, IMyGrain
{
private readonly MyComponent _component;
public MyGrain(MyComponent component)
{
_component = component;
}
}