示例#1
0
文件: MainGrain.cs 项目: pangfd/Ray
        protected async ValueTask Archive(bool force = false)
        {
            if (Snapshot.Base.Version != Snapshot.Base.DoingVersion)
            {
                throw new StateInsecurityException(Snapshot.Base.StateId.ToString(), GrainType, Snapshot.Base.DoingVersion, Snapshot.Base.Version);
            }
            if (force || NewArchive.IsCompletedArchive(ArchiveOptions, LastArchive))
            {
                var task = OnStartArchive();
                if (!task.IsCompletedSuccessfully)
                {
                    await task;
                }
                await ArchiveStorage.Insert(NewArchive, Snapshot);

                BriefArchiveList.Add(NewArchive);
                LastArchive = NewArchive;
                NewArchive  = default;
                var onTask = OnArchiveCompleted();
                if (!onTask.IsCompletedSuccessfully)
                {
                    await onTask;
                }
            }
        }
示例#2
0
文件: MainGrain.cs 项目: pangfd/Ray
        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]);
                            }
                        }
                    }
                }
            }
        }
示例#3
0
文件: MainGrain.cs 项目: pangfd/Ray
        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();
            }
        }
示例#4
0
        /// <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;
            }
        }