我们使用 Orleans Grain 作为会话,用事件填充会话,并希望在会话过期后(20 分钟不活动后)将会话保存到外部服务。最初我们打算使用 GrainCollectionOptions.CollectionAge 来保存停用时的会话,但在不同的来源中发现依赖 OnDeactivateAsync 并不安全,因为它可能并不总是被调用,特别是在筒仓崩溃或硬关闭期间。
有人可以建议针对此类用例的推荐方法吗?
这是我们的 Grain 代码:
public class SessionGrain : Grain, ISessionGrain
{
private readonly IPersistentState<Session> _persistentState;
public SessionGrain([PersistentState("sessionsState", "sessionsStorage")] IPersistentState<Session> persistentState)
{
_persistentState = persistentState;
}
public Task CompleteAsync()
{
DeactivateOnIdle();
return Task.CompletedTask;
}
public async Task<Session> TrackEventAsync(Event @event)
{
_persistentState.State.Events.Add(@event);
await _persistentState.WriteStateAsync();
return _persistentState.State;
}
public override async Task OnActivateAsync()
{
if (_persistentState.State == null)
{
_persistentState.State = new Session();
}
await base.OnActivateAsync();
}
public override async Task OnDeactivateAsync()
{
// TODO: SAVE TO EXTERNAL SERVICE HERE???
await _persistentState.ClearStateAsync();
await base.OnDeactivateAsync();
}
}
Run Code Online (Sandbox Code Playgroud)
如果持久状态至关重要并且无法重建,那么您必须在返回给调用者之前立即保存它,以便调用者可以在发生故障时重试。如果发生故障(例如电源故障,但还有许多其他类型的事件会导致相同的行为),任何未持久保存的数据都将丢失。
如果发生故障时丢失数据是可以接受的,那么您有几个选择:
this.RegisterTimer(...))在一段空闲时间后保存状态| 归档时间: |
|
| 查看次数: |
649 次 |
| 最近记录: |