public override async Task OnActivateAsync() { await base.OnActivateAsync(); //如果失活之前已提交事务还没有Complete,则消耗信号量,防止产生新的事物 if (Snapshot.Base is TxSnapshotBase <PrimaryKey> snapshotBase) { if (snapshotBase.TransactionId != 0) { await TransactionSemaphore.WaitAsync(); var waitingEvents = await EventStorage.GetList(GrainId, snapshotBase.TransactionStartTimestamp, snapshotBase.TransactionStartVersion, Snapshot.Base.Version); foreach (var evt in waitingEvents) { var evtType = evt.Event.GetType(); WaitingForTransactionTransports.Add(new EventTransport <PrimaryKey>(evt, string.Empty, evt.StateId.ToString()) { BytesTransport = new EventBytesTransport( TypeContainer.GetTypeCode(evtType), GrainId, evt.Base.GetBytes(), Serializer.SerializeToUtf8Bytes(evt.Event, evtType) ) }); } CurrentTransactionId = snapshotBase.TransactionId; CurrentTransactionStartVersion = snapshotBase.TransactionStartVersion; } } else { throw new SnapshotNotSupportTxException(Snapshot.GetType()); } }
protected async ValueTask Tell(IFullyEvent <PrimaryKey> @event) { if (Logger.IsEnabled(LogLevel.Trace)) { Logger.LogTrace(LogEventIds.FollowEventProcessing, "Start event handling, grain Id = {0} and state version = {1},event type = {2} ,event = {3}", GrainId.ToString(), Snapshot.Version, @event.GetType().FullName, Serializer.SerializeToString(@event)); } try { if (@event.Base.Version == Snapshot.Version + 1) { var onEventDeliveredTask = OnEventDelivered(@event); if (!onEventDeliveredTask.IsCompletedSuccessfully) { await onEventDeliveredTask; } Snapshot.FullUpdateVersion(@event.Base, GrainType);//更新处理完成的Version } else if (@event.Base.Version > Snapshot.Version) { var eventList = await EventStorage.GetList(GrainId, Snapshot.StartTimestamp, Snapshot.Version + 1, @event.Base.Version - 1); foreach (var evt in eventList) { var onEventDeliveredTask = OnEventDelivered(evt); if (!onEventDeliveredTask.IsCompletedSuccessfully) { await onEventDeliveredTask; } Snapshot.FullUpdateVersion(evt.Base, GrainType);//更新处理完成的Version } } if (@event.Base.Version == Snapshot.Version + 1) { var onEventDeliveredTask = OnEventDelivered(@event); if (!onEventDeliveredTask.IsCompletedSuccessfully) { await onEventDeliveredTask; } Snapshot.FullUpdateVersion(@event.Base, GrainType);//更新处理完成的Version } if (@event.Base.Version > Snapshot.Version) { throw new EventVersionNotMatchStateException(GrainId.ToString(), GrainType, @event.Base.Version, Snapshot.Version); } await SaveSnapshotAsync(); if (Logger.IsEnabled(LogLevel.Trace)) { Logger.LogTrace(LogEventIds.FollowEventProcessing, "Event Handling Completion, grain Id ={0} and state version = {1},event type = {2}", GrainId.ToString(), Snapshot.Version, @event.GetType().FullName); } } catch (Exception ex) { if (Logger.IsEnabled(LogLevel.Critical)) { Logger.LogCritical(LogEventIds.FollowEventProcessing, ex, "FollowGrain Event handling failed with Id = {0},event = {1}", GrainId.ToString(), Serializer.SerializeToString(@event)); } throw; } }
public override async Task OnActivateAsync() { await base.OnActivateAsync(); //如果失活之前已提交事务还没有Complete,则消耗信号量,防止产生新的事物 if (Snapshot.Base.TransactionId != 0) { await TransactionSemaphore.WaitAsync(); var waitingEvents = await EventStorage.GetList(GrainId, Snapshot.Base.TransactionStartTimestamp, Snapshot.Base.TransactionStartVersion, Snapshot.Base.Version); foreach (var evt in waitingEvents) { WaitingForTransactionTransports.Add(new EventTransport <PrimaryKey>(evt, string.Empty, evt.StateId.ToString()) { BytesTransport = new EventBytesTransport { EventType = evt.Event.GetType().FullName, GrainId = GrainId, EventBytes = Serializer.SerializeToBytes(evt.Event), BaseBytes = evt.Base.GetBytes() } }); } CurrentTransactionId = Snapshot.Base.TransactionId; CurrentTransactionStartVersion = Snapshot.Base.TransactionStartVersion; } }
private async Task FullActive() { while (true) { var eventList = await EventStorage.GetList(GrainId, Snapshot.StartTimestamp, Snapshot.Version + 1, Snapshot.Version + ConfigOptions.NumberOfEventsPerRead); if (EventConcurrentProcessing) { await Task.WhenAll(eventList.Select(@event => { var task = OnEventDelivered(@event); if (!task.IsCompletedSuccessfully) { return(task.AsTask()); } else { return(Task.CompletedTask); } })); var lastEvt = eventList.Last(); Snapshot.UnsafeUpdateVersion(lastEvt.Base); } else { foreach (var @event in eventList) { Snapshot.IncrementDoingVersion(GrainType);//标记将要处理的Version var task = OnEventDelivered(@event); if (!task.IsCompletedSuccessfully) { await task; } Snapshot.UpdateVersion(@event.Base, GrainType);//更新处理完成的Version } } var saveTask = SaveSnapshotAsync(); if (!saveTask.IsCompletedSuccessfully) { await saveTask; } if (eventList.Count < ConfigOptions.NumberOfEventsPerRead) { break; } } ; }
protected async ValueTask Tell(IFullyEvent <PrimaryKey> @event) { try { if (@event.Base.Version == Snapshot.Base.Version + 1) { var onEventDeliveredTask = OnEventDelivered(@event); if (!onEventDeliveredTask.IsCompletedSuccessfully) { await onEventDeliveredTask; } Snapshot.Base.FullUpdateVersion(@event.Base, GrainType);//更新处理完成的Version } else if (@event.Base.Version > Snapshot.Base.Version) { var eventList = await EventStorage.GetList(GrainId, Snapshot.Base.StartTimestamp, Snapshot.Base.Version + 1, @event.Base.Version - 1); foreach (var evt in eventList) { var onEventDeliveredTask = OnEventDelivered(evt); if (!onEventDeliveredTask.IsCompletedSuccessfully) { await onEventDeliveredTask; } Snapshot.Base.FullUpdateVersion(evt.Base, GrainType);//更新处理完成的Version } } if (@event.Base.Version == Snapshot.Base.Version + 1) { var onEventDeliveredTask = OnEventDelivered(@event); if (!onEventDeliveredTask.IsCompletedSuccessfully) { await onEventDeliveredTask; } Snapshot.Base.FullUpdateVersion(@event.Base, GrainType);//更新处理完成的Version } if (@event.Base.Version > Snapshot.Base.Version) { throw new EventVersionUnorderedException(GrainId.ToString(), GrainType, @event.Base.Version, Snapshot.Base.Version); } } catch (Exception ex) { Logger.LogCritical(ex, "{0}({1})", @event.GetType().FullName, Serializer.Serialize(@event, @event.GetType())); throw; } }
public override async Task OnActivateAsync() { var dITask = DependencyInjection(); if (!dITask.IsCompletedSuccessfully) { await dITask; } try { if (ArchiveOptions.On) { //加载最后一条归档 LastArchive = await ArchiveStorage.GetLatestBrief(GrainId); } await ReadSnapshotAsync(); if (FullyActive) { while (true) { var eventList = await EventStorage.GetList(GrainId, Snapshot.Base.StartTimestamp, Snapshot.Base.Version + 1, Snapshot.Base.Version + NumberOfEventsPerRead); var task = Tell(eventList); if (!task.IsCompletedSuccessfully) { await task; } if (eventList.Count < NumberOfEventsPerRead) { break; } } ; } if (Logger.IsEnabled(LogLevel.Trace)) { Logger.LogTrace("Activation completed: {0}->{1}", GrainType.FullName, Serializer.Serialize(Snapshot)); } } catch (Exception ex) { Logger.LogCritical(ex, "Activation failed: {0}->{1}", GrainType.FullName, GrainId.ToString()); throw; } }
/// <summary> /// 从库里恢复 /// </summary> /// <returns></returns> private async Task RecoveryFromStorage() { while (true) { var eventList = await EventStorage.GetList(GrainId, Snapshot.Base.StartTimestamp, Snapshot.Base.Version + 1, Snapshot.Base.Version + NumberOfEventsPerRead); var task = Tell(eventList); if (!task.IsCompletedSuccessfully) { await task; } if (eventList.Count < NumberOfEventsPerRead) { break; } } ; }
protected virtual async Task RecoverySnapshot() { try { await ReadSnapshotAsync(); while (!Snapshot.Base.IsLatest) { var eventList = await EventStorage.GetList(GrainId, Snapshot.Base.LatestMinEventTimestamp, Snapshot.Base.Version + 1, Snapshot.Base.Version + CoreOptions.NumberOfEventsPerRead); foreach (var fullyEvent in eventList) { Snapshot.Base.IncrementDoingVersion(GrainType); //标记将要处理的Version SnapshotHandler.Apply(Snapshot, fullyEvent); Snapshot.Base.UpdateVersion(fullyEvent.Base, GrainType); //更新处理完成的Version } if (eventList.Count < CoreOptions.NumberOfEventsPerRead) { break; } } ; if (Snapshot.Base.Version - SnapshotEventVersion >= CoreOptions.MinSnapshotVersionInterval) { var saveTask = SaveSnapshotAsync(true, true); if (!saveTask.IsCompletedSuccessfully) { await saveTask; } } if (Logger.IsEnabled(LogLevel.Trace)) { Logger.LogTrace("Recovery completed: {0}->{1}", GrainType.FullName, Serializer.Serialize(Snapshot)); } } catch (Exception ex) { Logger.LogCritical(ex, "Recovery failed: {0}->{1}", GrainType.FullName, GrainId.ToString()); throw; } }
protected async ValueTask Tell(IFullyEvent <PrimaryKey> @event) { if (@event.Base.Version == Snapshot.Base.Version + 1) { var onEventDeliveredTask = OnEventDelivered(@event); if (!onEventDeliveredTask.IsCompletedSuccessfully) { await onEventDeliveredTask; } Snapshot.Base.FullUpdateVersion(@event.Base, GrainType);//更新处理完成的Version } else if (@event.Base.Version > Snapshot.Base.Version) { var eventList = await EventStorage.GetList(GrainId, Snapshot.Base.StartTimestamp, Snapshot.Base.Version + 1, @event.Base.Version - 1); foreach (var evt in eventList) { var onEventDeliveredTask = OnEventDelivered(evt); if (!onEventDeliveredTask.IsCompletedSuccessfully) { await onEventDeliveredTask; } Snapshot.Base.FullUpdateVersion(evt.Base, GrainType);//更新处理完成的Version } } if (@event.Base.Version == Snapshot.Base.Version + 1) { var onEventDeliveredTask = OnEventDelivered(@event); if (!onEventDeliveredTask.IsCompletedSuccessfully) { await onEventDeliveredTask; } Snapshot.Base.FullUpdateVersion(@event.Base, GrainType);//更新处理完成的Version } if (@event.Base.Version > Snapshot.Base.Version) { throw new EventVersionUnorderedException(GrainId.ToString(), GrainType, @event.Base.Version, Snapshot.Base.Version); } }
private async Task FullActive() { while (true) { var eventList = await EventStorage.GetList(GrainId, Snapshot.Base.StartTimestamp, Snapshot.Base.Version + 1, Snapshot.Base.Version + NumberOfEventsPerRead); foreach (var @event in eventList) { Snapshot.Base.IncrementDoingVersion(GrainType);//标记将要处理的Version var task = OnEventDelivered(@event); if (!task.IsCompletedSuccessfully) { await task; } Snapshot.Base.UpdateVersion(@event.Base, GrainType);//更新处理完成的Version } if (eventList.Count < NumberOfEventsPerRead) { break; } } ; }
protected virtual async Task RecoverySnapshot() { if (Logger.IsEnabled(LogLevel.Trace)) { Logger.LogTrace("The state of id = {0} begin to recover", GrainId.ToString()); } try { await ReadSnapshotAsync(); while (!Snapshot.Base.IsLatest) { var eventList = await EventStorage.GetList(GrainId, Snapshot.Base.LatestMinEventTimestamp, Snapshot.Base.Version + 1, Snapshot.Base.Version + CoreOptions.NumberOfEventsPerRead); foreach (var fullyEvent in eventList) { Snapshot.Base.IncrementDoingVersion(GrainType); //标记将要处理的Version EventHandler.Apply(Snapshot, fullyEvent); Snapshot.Base.UpdateVersion(fullyEvent.Base, GrainType); //更新处理完成的Version } if (eventList.Count < CoreOptions.NumberOfEventsPerRead) { break; } } ; if (Logger.IsEnabled(LogLevel.Trace)) { Logger.LogTrace("The state of id = {0} recovery has been completed ,state version = {1}", GrainId.ToString(), Snapshot.Base.Version); } } catch (Exception ex) { Logger.LogCritical(ex, "The state of id = {0} recovery has failed ,state version = {1}", GrainId.ToString(), Snapshot.Base.Version); throw; } }
/// <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; } }
private async Task BatchInputProcessing(List <AsyncInputEvent <IFullyEvent <PrimaryKey>, bool> > eventInputs) { var evtList = new List <IFullyEvent <PrimaryKey> >(); var startVersion = Snapshot.Version; if (UnprocessedEventList.Count > 0) { startVersion = UnprocessedEventList.Last().Base.Version; } var maxVersion = startVersion; TaskCompletionSource <bool> maxRequest = default; try { foreach (var input in eventInputs) { if (input.Value.Base.Version == startVersion) { maxRequest = input.TaskSource; } else if (input.Value.Base.Version < startVersion) { input.TaskSource.TrySetResult(true); } else { evtList.Add(input.Value); if (input.Value.Base.Version > maxVersion) { maxRequest?.TrySetResult(true); maxVersion = input.Value.Base.Version; maxRequest = input.TaskSource; } else { input.TaskSource.TrySetResult(true); } } } if (evtList.Count > 0) { var orderList = evtList.OrderBy(e => e.Base.Version).ToList(); var inputLast = orderList.Last(); if (startVersion + orderList.Count < inputLast.Base.Version) { var loadList = await EventStorage.GetList(GrainId, 0, startVersion + 1, inputLast.Base.Version - 1); UnprocessedEventList.AddRange(loadList); UnprocessedEventList.Add(inputLast); } else { UnprocessedEventList.AddRange(orderList.Select(w => w)); } } if (UnprocessedEventList.Count > 0) { await Task.WhenAll(UnprocessedEventList.Select(async @event => { var task = EventDelivered(@event); if (!task.IsCompletedSuccessfully) { await task; } })); Snapshot.UnsafeUpdateVersion(UnprocessedEventList.Last().Base); var saveTask = SaveSnapshotAsync(); if (!saveTask.IsCompletedSuccessfully) { await saveTask; } UnprocessedEventList.Clear(); maxRequest?.TrySetResult(true); } } catch (Exception ex) { Logger.LogError(ex, "FollowGrain event handling failed with Id {1}", GrainId.ToString()); maxRequest?.TrySetException(ex); } }
private async Task BatchInputProcessing(List <DataAsyncWrapper <IFullyEvent <PrimaryKey>, bool> > events) { var evtList = new List <IFullyEvent <PrimaryKey> >(); var startVersion = Snapshot.Version; if (UnprocessedEventList.Count > 0) { startVersion = UnprocessedEventList.Last().Base.Version; } var maxVersion = startVersion; TaskCompletionSource <bool> maxRequest = default; try { foreach (var wrap in events) { if (wrap.Value.Base.Version <= startVersion) { wrap.TaskSource.TrySetResult(true); } else { evtList.Add(wrap.Value); if (wrap.Value.Base.Version > maxVersion) { maxRequest?.TrySetResult(true); maxVersion = wrap.Value.Base.Version; maxRequest = wrap.TaskSource; } else { wrap.TaskSource.TrySetResult(true); } } } var orderList = evtList.OrderBy(e => e.Base.Version).ToList(); if (orderList.Count > 0) { var inputLast = orderList.Last(); if (startVersion + orderList.Count < inputLast.Base.Version) { var loadList = await EventStorage.GetList(GrainId, 0, startVersion + 1, inputLast.Base.Version - 1); UnprocessedEventList.AddRange(loadList); } else { UnprocessedEventList.AddRange(orderList.Select(w => w)); } } if (UnprocessedEventList.Count > 0) { using (var tokenSource = new CancellationTokenSource()) { var allTask = Task.WhenAll(UnprocessedEventList.Select(@event => { var task = OnEventDelivered(@event); if (!task.IsCompletedSuccessfully) { return(task.AsTask()); } else { return(Task.CompletedTask); } })); using (var delayTask = Task.Delay(ConfigOptions.EventAsyncProcessTimeoutSeconds, tokenSource.Token)) { await Task.WhenAny(allTask, delayTask); if (allTask.Status == TaskStatus.RanToCompletion) { tokenSource.Cancel(); var lastEvt = UnprocessedEventList.Last(); var lastEvtBase = lastEvt.Base; Snapshot.UnsafeUpdateVersion(lastEvtBase); var saveTask = SaveSnapshotAsync(); if (!saveTask.IsCompletedSuccessfully) { await saveTask; } UnprocessedEventList.Clear(); maxRequest?.TrySetResult(true); } else { maxRequest?.TrySetException(timeoutException); } } } } } catch (Exception ex) { Logger.LogError(ex, "FollowGrain event handling failed with Id {1}", GrainId.ToString()); maxRequest?.TrySetException(ex); } }