protected virtual async ValueTask OnArchiveCompleted() { //开始执行事件清理逻辑 var noCleareds = BriefArchiveList.Where(a => !a.EventIsCleared).ToList(); if (noCleareds.Count >= ArchiveOptions.MaxSnapshotArchiveRecords) { var minArchive = noCleareds.FirstOrDefault(); if (minArchive != default) { //判断需要清理的event是否都被follow执行过 var versions = await Task.WhenAll(FollowUnit.GetAndSaveVersionFuncs().Select(func => func(Snapshot.Base.StateId, Snapshot.Base.Version))); if (versions.All(v => v >= minArchive.EndVersion)) { //清理归档对应的事件 await ArchiveStorage.EventIsClear(Snapshot.Base.StateId, minArchive.Id); minArchive.EventIsCleared = true; //如果快照的版本小于需要清理的最大事件版本号,则保存快照 if (SnapshotEventVersion < minArchive.EndVersion) { var saveTask = SaveSnapshotAsync(true); if (!saveTask.IsCompletedSuccessfully) { await saveTask; } } if (ArchiveOptions.DeleteEvents) { await EventStorage.DeleteStart(Snapshot.Base.StateId, minArchive.EndVersion, Snapshot.Base.StartTimestamp); } else { await ArchiveStorage.EventArichive(Snapshot.Base.StateId, minArchive.EndVersion, Snapshot.Base.StartTimestamp); } ClearedArchive = minArchive; //只保留一个清理过事件的快照,其它的删除掉 var cleareds = BriefArchiveList.Where(a => a.EventIsCleared).OrderBy(a => a.Index).ToArray(); if (cleareds.Length > 1) { for (int i = 0; i < cleareds.Length - 1; i++) { await DeleteArchive(cleareds[i].Id); BriefArchiveList.Remove(cleareds[i]); } } } } } }
protected virtual async ValueTask OnRaiseStart(IFullyEvent <PrimaryKey> @event) { if (Snapshot.Base.Version == 0) { return; } if (Snapshot.Base.IsLatest) { await SnapshotStorage.UpdateIsLatest(Snapshot.Base.StateId, false); Snapshot.Base.IsLatest = false; } if (ClearedArchive != default && @event.Base.Timestamp < ClearedArchive.StartTimestamp) { throw new EventIsClearedException(@event.GetType().FullName, Serializer.SerializeToString(@event), ClearedArchive.Index); } if (SnapshotEventVersion > 0) { if (@event.Base.Timestamp < Snapshot.Base.LatestMinEventTimestamp) { await SnapshotStorage.UpdateLatestMinEventTimestamp(Snapshot.Base.StateId, @event.Base.Timestamp); } if (@event.Base.Timestamp < Snapshot.Base.StartTimestamp) { await SnapshotStorage.UpdateStartTimestamp(Snapshot.Base.StateId, @event.Base.Timestamp); } } if (ArchiveOptions.On && LastArchive != default && @event.Base.Timestamp < LastArchive.EndTimestamp) { foreach (var archive in BriefArchiveList.Where(a => @event.Base.Timestamp < a.EndTimestamp && !a.EventIsCleared).OrderByDescending(v => v.Index)) { if (@event.Base.Timestamp < archive.EndTimestamp) { await DeleteArchive(archive.Id); if (NewArchive != default) { NewArchive = CombineArchiveInfo(archive, NewArchive); } else { NewArchive = archive; } BriefArchiveList.Remove(archive); } } LastArchive = BriefArchiveList.LastOrDefault(); } }
/// <summary> /// Grain激活时调用用来初始化的方法(禁止在子类重写,请使用) /// </summary> /// <returns></returns> public override async Task OnActivateAsync() { var dITask = DependencyInjection(); if (Logger.IsEnabled(LogLevel.Trace)) { Logger.LogTrace("Start activation with id = {0}", GrainId.ToString()); } if (!dITask.IsCompletedSuccessfully) { await dITask; } try { if (ArchiveOptions.On) { //加载归档信息 BriefArchiveList = (await ArchiveStorage.GetBriefList(GrainId)).OrderBy(a => a.Index).ToList(); LastArchive = BriefArchiveList.LastOrDefault(); ClearedArchive = BriefArchiveList.Where(a => a.EventIsCleared).OrderByDescending(a => a.Index).FirstOrDefault(); var secondLastArchive = BriefArchiveList.Count > 1 ? BriefArchiveList.SkipLast(1).Last() : default; if (LastArchive != default && !LastArchive.IsCompletedArchive(ArchiveOptions, secondLastArchive) && !LastArchive.EventIsCleared) { await DeleteArchive(LastArchive.Id); BriefArchiveList.Remove(LastArchive); NewArchive = LastArchive; LastArchive = BriefArchiveList.LastOrDefault(); } } //修复状态 await RecoverySnapshot(); if (ArchiveOptions.On) { if (Snapshot.Base.Version != 0 && (LastArchive == default || LastArchive.EndVersion < Snapshot.Base.Version) && (NewArchive == default || NewArchive.EndVersion < Snapshot.Base.Version)) { //归档恢复 while (true) { var startTimestamp = Snapshot.Base.StartTimestamp; long startVersion = 0; if (NewArchive != default) { startVersion = NewArchive.EndVersion; startTimestamp = NewArchive.StartTimestamp; } else if (NewArchive == default && LastArchive != default) { startVersion = LastArchive.EndVersion; startTimestamp = LastArchive.EndTimestamp; } var eventList = await EventStorage.GetList(GrainId, startTimestamp, startVersion + 1, startVersion + CoreOptions.NumberOfEventsPerRead); foreach (var @event in eventList) { var task = EventArchive(@event); if (!task.IsCompletedSuccessfully) { await task; } } if (eventList.Count < CoreOptions.NumberOfEventsPerRead) { break; } } ; } } var onActivatedTask = OnBaseActivated(); if (!onActivatedTask.IsCompletedSuccessfully) { await onActivatedTask; } if (Logger.IsEnabled(LogLevel.Trace)) { Logger.LogTrace("Activation completed with id = {0}", GrainId.ToString()); } } catch (Exception ex) { Logger.LogCritical(ex, "Activation failed with Id = {0}", GrainId.ToString()); throw; } }