Example #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(
                                TypeFinder.GetCode(evtType),
                                GrainId,
                                evt.Base.GetBytes(),
                                Serializer.SerializeToUtf8Bytes(evt.Event, evtType)
                                )
                        });
                    }
                    CurrentTransactionId           = snapshotBase.TransactionId;
                    CurrentTransactionStartVersion = snapshotBase.TransactionStartVersion;
                }
            }
            else
            {
                throw new SnapshotNotSupportTxException(Snapshot.GetType());
            }
        }
Example #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(
                            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;
                }
            }
        }
Example #3
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(
                    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;
                    }
                }
            }