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( TypeFinder.GetCode(evtType), GrainId, evt.Base.GetBytes(), Serializer.SerializeToUtf8Bytes(evt.Event, evtType) ) }); } CurrentTransactionId = snapshotBase.TransactionId; CurrentTransactionStartVersion = snapshotBase.TransactionStartVersion; } } else { throw new SnapshotNotSupportTxException(Snapshot.GetType()); } }
public async Task CommitTransaction(long transactionId) { if (WaitingForTransactionTransports.Count > 0) { if (CurrentTransactionId != transactionId) { throw new TxCommitException(); } try { var onCommitTask = OnCommitTransaction(transactionId); if (!onCommitTask.IsCompletedSuccessfully) { await onCommitTask; } foreach (var transport in WaitingForTransactionTransports) { var startTask = OnRaiseStart(transport.FullyEvent); if (!startTask.IsCompletedSuccessfully) { await startTask; } var evtType = transport.FullyEvent.Event.GetType(); transport.BytesTransport = new EventBytesTransport( TypeFinder.GetCode(evtType), GrainId, transport.FullyEvent.Base.GetBytes(), Serializer.SerializeToUtf8Bytes(transport.FullyEvent.Event, evtType) ); } await EventStorage.TransactionBatchAppend(WaitingForTransactionTransports); if (Logger.IsEnabled(LogLevel.Trace)) { Logger.LogTrace("Transaction Commited: {0}->{1}->{2}", GrainType.FullName, GrainId.ToString(), transactionId); } } catch (Exception ex) { Logger.LogCritical(ex, "Transaction failed: {0}->{1}->{2}", GrainType.FullName, GrainId.ToString(), transactionId); throw; } } }
protected virtual async Task <bool> RaiseEvent(IEvent @event, EventUID eUID = null) { if (Snapshot.Base.IsOver) { throw new StateIsOverException(Snapshot.Base.StateId.ToString(), GrainType); } try { var fullyEvent = new FullyEvent <PrimaryKey> { Event = @event, Base = new EventBase { Version = Snapshot.Base.Version + 1 }, StateId = Snapshot.Base.StateId }; string unique = default; if (eUID is null) { fullyEvent.Base.Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); unique = fullyEvent.GetEventId(); } else { fullyEvent.Base.Timestamp = eUID.Timestamp; unique = eUID.UID; } var startTask = OnRaiseStart(fullyEvent); if (!startTask.IsCompletedSuccessfully) { await startTask; } Snapshot.Base.IncrementDoingVersion(GrainType);//标记将要处理的Version var evtType = @event.GetType(); var bytesTransport = new EventBytesTransport( TypeFinder.GetCode(evtType), Snapshot.Base.StateId, fullyEvent.Base.GetBytes(), Serializer.SerializeToUtf8Bytes(@event, evtType) ); if (await EventStorage.Append(fullyEvent, in bytesTransport, unique)) { SnapshotHandler.Apply(Snapshot, fullyEvent); Snapshot.Base.UpdateVersion(fullyEvent.Base, GrainType);//更新处理完成的Version var task = OnRaised(fullyEvent, bytesTransport); if (!task.IsCompletedSuccessfully) { await task; } var saveSnapshotTask = SaveSnapshotAsync(); if (!saveSnapshotTask.IsCompletedSuccessfully) { await saveSnapshotTask; } await PublishToEventBus(bytesTransport.GetBytes(), GrainId.ToString()); if (Logger.IsEnabled(LogLevel.Trace)) { Logger.LogTrace("RaiseEvent completed: {0}->{1}->{2}", GrainType.FullName, Serializer.Serialize(fullyEvent), Serializer.Serialize(Snapshot)); } return(true); } else { if (Logger.IsEnabled(LogLevel.Trace)) { Logger.LogTrace("RaiseEvent failed: {0}->{1}->{2}", GrainType.FullName, Serializer.Serialize(fullyEvent), Serializer.Serialize(Snapshot)); } Snapshot.Base.DecrementDoingVersion();//还原doing Version var task = OnRaiseFailed(fullyEvent); if (!task.IsCompletedSuccessfully) { await task; } } }