Пример #1
0
        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());
            }
        }
Пример #2
0
        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(
                            TypeContainer.GetTypeCode(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;
                }
            }
        }
Пример #3
0
 public async Task CommitTransaction(long transactionId)
 {
     if (Logger.IsEnabled(LogLevel.Trace))
     {
         Logger.LogTrace("Commit transaction with id = {0},event counts = {1}, from version {2} to version {3}", GrainId.ToString(), WaitingForTransactionTransports.Count.ToString(), CurrentTransactionStartVersion.ToString(), Snapshot.Base.Version.ToString());
     }
     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(
                     TypeContainer.GetTypeCode(evtType),
                     GrainId,
                     transport.FullyEvent.Base.GetBytes(),
                     Serializer.SerializeToUtf8Bytes(transport.FullyEvent.Event, evtType)
                     );
             }
             await EventStorage.TransactionBatchAppend(WaitingForTransactionTransports);
         }
         catch (Exception ex)
         {
             Logger.LogError(ex, "Commit transaction failed, grain Id = {1}", GrainId.ToString());
             throw;
         }
     }
 }
Пример #4
0
        protected virtual async Task <bool> RaiseEvent(IEvent @event, EventUID uniqueId = null)
        {
            if (Logger.IsEnabled(LogLevel.Trace))
            {
                Logger.LogTrace("Start raise event, grain Id ={0} and state version = {1},event type = {2} ,event ={3},uniqueueId= {4}", GrainId.ToString(), Snapshot.Base.Version, @event.GetType().FullName, Serializer.SerializeToString(@event), uniqueId);
            }
            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
                };
                if (uniqueId == default)
                {
                    uniqueId = EventUID.Empty;
                }
                if (string.IsNullOrEmpty(uniqueId.UID))
                {
                    fullyEvent.Base.Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
                }
                else
                {
                    fullyEvent.Base.Timestamp = uniqueId.Timestamp;
                }
                var startTask = OnRaiseStart(fullyEvent);
                if (!startTask.IsCompletedSuccessfully)
                {
                    await startTask;
                }
                Snapshot.Base.IncrementDoingVersion(GrainType);//标记将要处理的Version
                var bytesTransport = new EventBytesTransport(
                    TypeContainer.GetTypeCode(@event.GetType()),
                    Snapshot.Base.StateId,
                    fullyEvent.Base.GetBytes(),
                    Serializer.SerializeToBytes(@event)
                    );
                if (await EventStorage.Append(fullyEvent, in bytesTransport, uniqueId.UID))
                {
                    EventHandler.Apply(Snapshot, fullyEvent);
                    Snapshot.Base.UpdateVersion(fullyEvent.Base, GrainType);//更新处理完成的Version
                    var task = OnRaiseSuccessed(fullyEvent, bytesTransport);
                    if (!task.IsCompletedSuccessfully)
                    {
                        await task;
                    }
                    var saveSnapshotTask = SaveSnapshotAsync();
                    if (!saveSnapshotTask.IsCompletedSuccessfully)
                    {
                        await saveSnapshotTask;
                    }
                    await PublishToEventBust(bytesTransport);

                    if (Logger.IsEnabled(LogLevel.Trace))
                    {
                        Logger.LogTrace("Raise event successfully, grain Id= {0} and state version = {1}", GrainId.ToString(), Snapshot.Base.Version);
                    }
                    return(true);
                }
                else
                {
                    Snapshot.Base.DecrementDoingVersion();//还原doing Version
                    if (Logger.IsEnabled(LogLevel.Information))
                    {
                        Logger.LogInformation("Raise event failure because of idempotency limitation, grain Id = {0},state version = {1},event type = {2} with version = {3}", GrainId.ToString(), Snapshot.Base.Version, @event.GetType().FullName, fullyEvent.Base.Version);
                    }
                    var task = OnRaiseFailed(fullyEvent);
                    if (!task.IsCompletedSuccessfully)
                    {
                        await task;
                    }
                }
            }
Пример #5
0
        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(
                    TypeContainer.GetTypeCode(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;
                    }
                }
            }