Esempio n. 1
0
        public async Task<RemoteClusterActivationResponse> ProcessActivationRequest(GrainId grain, string requestClusterId, int hopCount = 0)
        {
            // check if the requesting cluster id is in the current configuration view of this cluster
            // if not, reject the message.
            var multiClusterConfiguration = Runtime.Silo.CurrentSilo.LocalMultiClusterOracle?.GetMultiClusterConfiguration();
            if (multiClusterConfiguration == null || !multiClusterConfiguration.Clusters.Contains(requestClusterId))       
            {
                logger.Warn(ErrorCode.GlobalSingleInstance_WarningInvalidOrigin, 
                    "GSIP:Rsp {0} Origin={1} GSI request rejected because origin is not in MC configuration", grain.ToString(), requestClusterId);

                return new RemoteClusterActivationResponse(ActivationResponseStatus.Failed);
            }

            var forwardAddress = router.CheckIfShouldForward(grain, 0, "ProcessActivationRequest");

            // on all silos other than first, we insert a retry delay and recheck owner before forwarding
            if (hopCount > 0 && forwardAddress != null)
            {
                await Task.Delay(LocalGrainDirectory.RETRY_DELAY);
                forwardAddress = router.CheckIfShouldForward(grain, hopCount, "ProcessActivationRequest(recheck)");
            }

            if (forwardAddress == null)
            {
                return ProcessRequestLocal(grain, requestClusterId);
            }
            else
            {
                if (logger.IsVerbose2)
                    logger.Verbose("GSIP:Rsp {0} Origin={1} forward to {2}", grain.ToString(), requestClusterId, forwardAddress);

                var clusterGrainDir = InsideRuntimeClient.Current.InternalGrainFactory.GetSystemTarget<IClusterGrainDirectory>(Constants.ClusterDirectoryServiceId, forwardAddress);
                return await clusterGrainDir.ProcessActivationRequest(grain, requestClusterId, hopCount + 1);
            }
        }
Esempio n. 2
0
        internal async Task Start(StatisticsProviderManager statsManager, IMessageCenter transport, GrainId clientId)
        {
            runtimeStats.Start();

            // Configure Metrics
            IProvider statsProvider = null;
            if (!string.IsNullOrEmpty(config.StatisticsProviderName))
            {
                var extType = config.StatisticsProviderName;
                statsProvider = statsManager.GetProvider(extType);
                var metricsDataPublisher = statsProvider as IClientMetricsDataPublisher;
                if (metricsDataPublisher == null)
                {
                    var msg = String.Format("Trying to create {0} as a metrics publisher, but the provider is not configured."
                        , extType);
                    throw new ArgumentException(msg, "ProviderType (configuration)");
                }
                var configurableMetricsDataPublisher = metricsDataPublisher as IConfigurableClientMetricsDataPublisher;
                if (configurableMetricsDataPublisher != null)
                {
                    configurableMetricsDataPublisher.AddConfiguration(
                        config.DeploymentId, config.DNSHostName, clientId.ToString(), transport.MyAddress.Endpoint.Address);
                }
                tableStatistics = new ClientTableStatistics(transport, metricsDataPublisher, runtimeStats)
                {
                    MetricsTableWriteInterval = config.StatisticsMetricsTableWriteInterval
                };
            }
            else if (config.UseAzureSystemStore)
            {
                // Hook up to publish client metrics to Azure storage table
                var publisher = AssemblyLoader.LoadAndCreateInstance<IClientMetricsDataPublisher>(Constants.ORLEANS_AZURE_UTILS_DLL, logger);
                await publisher.Init(config, transport.MyAddress.Endpoint.Address, clientId.ToParsableString());
                tableStatistics = new ClientTableStatistics(transport, publisher, runtimeStats)
                {
                    MetricsTableWriteInterval = config.StatisticsMetricsTableWriteInterval
                };
            }

            // Configure Statistics
            if (config.StatisticsWriteLogStatisticsToTable)
            {
                if (statsProvider != null)
                {
                    logStatistics.StatsTablePublisher = statsProvider as IStatisticsPublisher;
                    // Note: Provider has already been Init-ialized above.
                }
                else if (config.UseAzureSystemStore)
                {
                    var statsDataPublisher = AssemblyLoader.LoadAndCreateInstance<IStatisticsPublisher>(Constants.ORLEANS_AZURE_UTILS_DLL, logger);
                    await statsDataPublisher.Init(false, config.DataConnectionString, config.DeploymentId,
                        transport.MyAddress.Endpoint.ToString(), clientId.ToParsableString(), config.DNSHostName);
                    logStatistics.StatsTablePublisher = statsDataPublisher;
                }
            }
            logStatistics.Start();
        }
        /// <summary>
        /// Removes an activation of the given grain from the partition
        /// </summary>
        /// <param name="grain">the identity of the grain</param>
        /// <param name="activation">the id of the activation</param>
        /// <param name="cause">reason for removing the activation</param>
        /// <param name="entry">returns the entry, if found </param>
        /// <param name="wasRemoved">returns whether the entry was actually removed</param>
        internal void RemoveActivation(GrainId grain, ActivationId activation, UnregistrationCause cause, out IActivationInfo entry, out bool wasRemoved)
        {
            wasRemoved = false;
            entry = null;
            lock (lockable)
            {
                if (partitionData.ContainsKey(grain) && partitionData[grain].RemoveActivation(activation, cause, out entry, out wasRemoved))
                    // if the last activation for the grain was removed, we remove the entire grain info 
                    partitionData.Remove(grain);

            }
            if (log.IsVerbose3)
                log.Verbose3("Removing activation for grain {0} cause={1} was_removed={2}", grain.ToString(), cause, wasRemoved);
        }
Esempio n. 4
0
        public async Task RollbackTransaction(long transactionId)
        {
            if (CurrentTransactionId == transactionId && CurrentTransactionStartVersion != -1 && Snapshot.Base.Version >= CurrentTransactionStartVersion)
            {
                try
                {
                    if (BackupSnapshot.Base.Version == CurrentTransactionStartVersion - 1)
                    {
                        Snapshot = new Snapshot <PrimaryKey, StateType>(GrainId)
                        {
                            Base  = BackupSnapshot.Base.Clone(),
                            State = BackupSnapshot.State.Clone()
                        };
                    }
                    else
                    {
                        if (BackupSnapshot.Base.Version >= CurrentTransactionStartVersion)
                        {
                            await EventStorage.DeleteAfter(Snapshot.Base.StateId, CurrentTransactionStartVersion, Snapshot.Base.LatestMinEventTimestamp);
                        }
                        await RecoverySnapshot();
                    }

                    WaitingForTransactionTransports.Clear();
                    RestoreTransactionTemporaryState();
                    TransactionSemaphore.Release();
                    if (Logger.IsEnabled(LogLevel.Trace))
                    {
                        Logger.LogTrace("Transaction rollbacked: {0}->{1}->{2}", GrainType.FullName, GrainId.ToString(), transactionId);
                    }
                }
                catch (Exception ex)
                {
                    Logger.LogCritical(ex, "Transaction rollback failed: {0}->{1}->{2}", GrainType.FullName, GrainId.ToString(), transactionId);
                    throw;
                }
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Grain激活时调用用来初始化的方法(禁止在子类重写,请使用)
        /// </summary>
        /// <returns></returns>
        public override async Task OnActivateAsync()
        {
            if (Logger.IsEnabled(LogLevel.Trace))
            {
                Logger.LogTrace("Start activation grain with id = {0}", GrainId.ToString());
            }
            var dITask = DependencyInjection();

            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 RecoveryState();

                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("Grain activation completed with id = {0}", GrainId.ToString());
                }
            }
            catch (Exception ex)
            {
                Logger.LogCritical(ex, "Grain activation failed with Id = {0}", GrainId.ToString());
                throw;
            }
        }
Esempio n. 6
0
        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(), this.Snapshot.Base.Version, @event.GetType().FullName, Serializer.SerializeToString(@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 EventVersionNotMatchStateException(GrainId.ToString(), GrainType, @event.Base.Version, this.Snapshot.Base.Version);
                }
                if (Logger.IsEnabled(LogLevel.Trace))
                {
                    Logger.LogTrace(LogEventIds.FollowEventProcessing, "Event Handling Completion, grain Id ={0} and state version = {1},event type = {2}", GrainId.ToString(), this.Snapshot.Base.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;
            }
        }
Esempio n. 7
0
 protected async Task BeginTransaction(long transactionId)
 {
     if (Logger.IsEnabled(LogLevel.Trace))
     {
         Logger.LogTrace("Transaction begin: {0}->{1}->{2}", GrainType.FullName, GrainId.ToString(), transactionId);
     }
     if (TransactionStartMilliseconds != 0 &&
         DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - TransactionStartMilliseconds > CoreOptions.TransactionMillisecondsTimeout)
     {
         if (await TransactionTimeoutLock.WaitAsync(CoreOptions.TransactionMillisecondsTimeout))
         {
             try
             {
                 if (TransactionStartMilliseconds != 0 &&
                     DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - TransactionStartMilliseconds > CoreOptions.TransactionMillisecondsTimeout)
                 {
                     if (Logger.IsEnabled(LogLevel.Trace))
                     {
                         Logger.LogTrace("Transaction timeout: {0}->{1}->{2}", GrainType.FullName, GrainId.ToString(), transactionId);
                     }
                     await RollbackTransaction(CurrentTransactionId);//事务超时自动回滚
                 }
             }
             finally
             {
                 TransactionTimeoutLock.Release();
             }
         }
     }
     if (await TransactionSemaphore.WaitAsync(CoreOptions.TransactionMillisecondsTimeout))
     {
         try
         {
             SnapshotCheck();
             CurrentTransactionStartVersion = Snapshot.Base.Version + 1;
             CurrentTransactionId           = transactionId;
             TransactionStartMilliseconds   = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
         }
         catch
         {
             TransactionSemaphore.Release();
             throw;
         }
     }
     else
     {
         throw new BeginTxTimeoutException(GrainId.ToString(), transactionId, GrainType);
     }
 }
Esempio n. 8
0
        public override Task OnDeactivateAsync()
        {
            var needSaveSnap = Snapshot.Version - SnapshotEventVersion >= 1;

            if (Logger.IsEnabled(LogLevel.Information))
            {
                Logger.LogInformation("Followgrain start deactivation with id = {0} ,{1}", GrainId.ToString(), needSaveSnap ? "updated snapshot" : "no update snapshot");
            }
            if (needSaveSnap)
            {
                return(SaveSnapshotAsync(true).AsTask());
            }
            else
            {
                return(Task.CompletedTask);
            }
        }
Esempio n. 9
0
        protected virtual async Task ReadSnapshotAsync()
        {
            if (Logger.IsEnabled(LogLevel.Trace))
            {
                Logger.LogTrace(LogEventIds.GrainSnapshot, "Start read snapshot  with Id = {0} ,state version = {1}", GrainId.ToString(), this.Snapshot.Base.Version);
            }
            try
            {
                Snapshot = await SnapshotStorage.Get(GrainId);

                if (Snapshot == default)
                {
                    //从归档中恢复状态
                    if (ArchiveOptions.On && LastArchive != default)
                    {
                        Snapshot = await ArchiveStorage.GetState(LastArchive.Id);
                    }
                }
                if (Snapshot == default)
                {
                    //新建状态
                    var createTask = CreateState();
                    if (!createTask.IsCompletedSuccessfully)
                    {
                        await createTask;
                    }
                }
                if (Logger.IsEnabled(LogLevel.Trace))
                {
                    Logger.LogTrace(LogEventIds.GrainSnapshot, "The snapshot of id = {0} read completed, state version = {1}", GrainId.ToString(), this.Snapshot.Base.Version);
                }
            }
            catch (Exception ex)
            {
                if (Logger.IsEnabled(LogLevel.Critical))
                {
                    Logger.LogCritical(LogEventIds.GrainSnapshot, ex, "The snapshot of id = {0} read failed", GrainId.ToString());
                }
                throw;
            }
        }
Esempio n. 10
0
 public async Task OnNext(Immutable <List <byte[]> > items)
 {
     var events = items.Value.Select(bytes =>
     {
         var(success, transport) = EventBytesTransport.FromBytesWithNoId(bytes);
         if (success)
         {
             var eventType = TypeFinder.FindType(transport.EventTypeCode);
             var data      = Serializer.Deserialize(transport.EventBytes, eventType);
             if (data is IEvent @event)
             {
                 var eventBase = EventBase.FromBytes(transport.BaseBytes);
                 if (eventBase.Version > Snapshot.Base.Version)
                 {
                     return(new FullyEvent <PrimaryKey>
                     {
                         StateId = GrainId,
                         Base = eventBase,
                         Event = @event
                     });
                 }
             }
             else
             {
                 if (Logger.IsEnabled(LogLevel.Trace))
                 {
                     Logger.LogTrace("Non-Event: {0}->{1}->{2}", GrainType.FullName, GrainId.ToString(), Serializer.Serialize(data, eventType));
                 }
             }
         }
         return(default);
Esempio n. 11
0
        protected virtual async ValueTask <bool> RaiseEvent(IEventBase <K> @event, string uniqueId = null, string hashKey = null)
        {
            try
            {
                State.IncrementDoingVersion();//标记将要处理的Version
                @event.StateId   = GrainId;
                @event.Version   = State.Version + 1;
                @event.Timestamp = DateTime.UtcNow;
                var serializer = GetSerializer();
                using (var ms = new PooledMemoryStream())
                {
                    serializer.Serialize(ms, @event);
                    var bytes = ms.ToArray();
                    if (await(await GetEventStorage()).SaveAsync(@event, bytes, uniqueId))
                    {
                        if (SupportAsync)
                        {
                            var data = new W
                            {
                                TypeCode    = @event.TypeCode,
                                BinaryBytes = bytes
                            };
                            ms.Position = 0;
                            ms.SetLength(0);
                            serializer.Serialize(ms, data);
                            //消息写入消息队列,以提供异步服务
                            Apply(State, @event);
                            GetMQService().Publish(ms.ToArray(), string.IsNullOrEmpty(hashKey) ? GrainId.ToString() : hashKey);
                        }
                        else
                        {
                            Apply(State, @event);
                        }
                        State.UpdateVersion(@event);//更新处理完成的Version
                        await SaveSnapshotAsync();

                        OnRaiseSuccess(@event, bytes);
                        return(true);
                    }
                    else
                    {
                        State.DecrementDoingVersion();//还原doing Version
                    }
                }
            }
            catch (Exception ex)
            {
                await RecoveryState();//还原状态

                ExceptionDispatchInfo.Capture(ex).Throw();
            }
            return(false);
        }
Esempio n. 12
0
        protected virtual async Task ReadSnapshotAsync()
        {
            try
            {
                Snapshot = await SnapshotStorage.Get(GrainId);

                if (Snapshot is null)
                {
                    //从归档中恢复状态
                    if (ArchiveOptions.On && LastArchive != null)
                    {
                        Snapshot = await ArchiveStorage.GetById(LastArchive.Id);
                    }
                }
                if (Snapshot is null)
                {
                    //新建状态
                    var createTask = CreateSnapshot();
                    if (!createTask.IsCompletedSuccessfully)
                    {
                        await createTask;
                    }
                }
                else if (IsTxShadow)
                {
                    Snapshot = new TxSnapshot <PrimaryKey, StateType>()
                    {
                        Base  = new TxSnapshotBase <PrimaryKey>(Snapshot.Base),
                        State = Snapshot.State
                    };
                }
                if (Logger.IsEnabled(LogLevel.Trace))
                {
                    Logger.LogTrace("ReadSnapshot completed: {0}->{1}", GrainType.FullName, Serializer.Serialize(Snapshot));
                }
            }
            catch (Exception ex)
            {
                Logger.LogCritical(ex, "ReadSnapshot failed: {0}->{1}", GrainType.FullName, GrainId.ToString());
                throw;
            }
        }
Esempio n. 13
0
 public Task OnNext(Immutable <byte[]> bytes)
 {
     var(success, transport) = EventBytesTransport.FromBytesWithNoId(bytes.Value);
     if (success)
     {
         var eventType = TypeFinder.FindType(transport.EventTypeCode);
         var data      = Serializer.Deserialize(transport.EventBytes, eventType);
         if (data is IEvent @event)
         {
             var eventBase = EventBase.FromBytes(transport.BaseBytes);
             if (eventBase.Version > Snapshot.Base.Version)
             {
                 var tellTask = Tell(new FullyEvent <PrimaryKey>
                 {
                     StateId = GrainId,
                     Base    = eventBase,
                     Event   = @event
                 });
                 if (!tellTask.IsCompletedSuccessfully)
                 {
                     return(tellTask.AsTask());
                 }
             }
             if (Logger.IsEnabled(LogLevel.Trace))
             {
                 Logger.LogTrace("OnNext completed: {0}->{1}->{2}", GrainType.FullName, GrainId.ToString(), Serializer.Serialize(data, eventType));
             }
         }
         else
         {
             if (Logger.IsEnabled(LogLevel.Trace))
             {
                 Logger.LogTrace("Non-Event: {0}->{1}->{2}", GrainType.FullName, GrainId.ToString(), Serializer.Serialize(data, eventType));
             }
         }
     }
     return(Task.CompletedTask);
 }
Esempio n. 14
0
        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)
                {
                    await RecoveryFromStorage();
                }
                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;
            }
        }
Esempio n. 15
0
 protected virtual async ValueTask SaveSnapshotAsync(bool force = false)
 {
     if (SaveSnapshot)
     {
         if (force || (Snapshot.Version - SnapshotEventVersion >= ConfigOptions.FollowSnapshotVersionInterval))
         {
             if (Logger.IsEnabled(LogLevel.Trace))
             {
                 Logger.LogTrace("Start saving state snapshots with Id = {0} ,state version = {1}", GrainId.ToString(), Snapshot.Version);
             }
             try
             {
                 var onSaveSnapshotTask = OnSaveSnapshot();//自定义保存项
                 if (!onSaveSnapshotTask.IsCompletedSuccessfully)
                 {
                     await onSaveSnapshotTask;
                 }
                 if (SnapshotEventVersion == 0)
                 {
                     await FollowSnapshotStorage.Insert(Snapshot);
                 }
                 else
                 {
                     await FollowSnapshotStorage.Update(Snapshot);
                 }
                 SnapshotEventVersion = Snapshot.Version;
                 var onSavedSnapshotTask = OnSavedSnapshot();
                 if (!onSavedSnapshotTask.IsCompletedSuccessfully)
                 {
                     await onSavedSnapshotTask;
                 }
                 if (Logger.IsEnabled(LogLevel.Trace))
                 {
                     Logger.LogTrace("State snapshot saved successfully with Id {0} ,state version = {1}", GrainId.ToString(), Snapshot.Version);
                 }
             }
             catch (Exception ex)
             {
                 Logger.LogError(ex, "State snapshot save failed with Id = {0}", GrainId.ToString());
                 throw;
             }
         }
     }
 }
Esempio n. 16
0
        protected virtual async Task ReadSnapshotAsync()
        {
            if (Logger.IsEnabled(LogLevel.Trace))
            {
                Logger.LogTrace("Start read snapshot  with Id = {0} ,state version = {1}", GrainId.ToString(), Snapshot.Version);
            }
            try
            {
                Snapshot = await FollowSnapshotStorage.Get(GrainId);

                if (Snapshot == null)
                {
                    var createTask = CreateState();
                    if (!createTask.IsCompletedSuccessfully)
                    {
                        await createTask;
                    }
                }
                SnapshotEventVersion = Snapshot.Version;
                if (Logger.IsEnabled(LogLevel.Trace))
                {
                    Logger.LogTrace("The snapshot of id = {0} read completed, state version = {1}", GrainId.ToString(), Snapshot.Version);
                }
            }
            catch (Exception ex)
            {
                Logger.LogCritical(ex, "The snapshot of id = {0} read failed", GrainId.ToString());
                throw;
            }
        }
Esempio n. 17
0
 /// <summary>
 /// Removes an activation of the given grain from the partition
 /// </summary>
 /// <param name="grain"></param>
 /// <param name="activation"></param>
 /// <param name="force"></param>
 internal void RemoveActivation(GrainId grain, ActivationId activation, bool force)
 {
     lock (lockable)
     {
         if (partitionData.ContainsKey(grain) && partitionData[grain].RemoveActivation(activation, force))
         {
             partitionData.Remove(grain);
         }
     }
     if (log.IsVerbose3) log.Verbose3("Removing activation for grain {0}", grain.ToString());
 }
Esempio n. 18
0
 /// <summary>
 /// Removes an activation of the given grain from the partition
 /// </summary>
 /// <param name="grain">the identity of the grain</param>
 /// <param name="activation">the id of the activation</param>
 /// <param name="cause">reason for removing the activation</param>
 /// <param name="entry">returns the entry, if found </param>
 /// <param name="wasRemoved">returns whether the entry was actually removed</param>
 internal void RemoveActivation(GrainId grain, ActivationId activation, UnregistrationCause cause, out IActivationInfo entry, out bool wasRemoved)
 {
     wasRemoved = false;
     entry      = null;
     lock (lockable)
     {
         if (partitionData.ContainsKey(grain) && partitionData[grain].RemoveActivation(activation, cause, out entry, out wasRemoved))
         {
             // if the last activation for the grain was removed, we remove the entire grain info
             partitionData.Remove(grain);
         }
     }
     if (log.IsVerbose3)
     {
         log.Verbose3("Removing activation for grain {0} cause={1} was_removed={2}", grain.ToString(), cause, wasRemoved);
     }
 }
Esempio n. 19
0
        public Task EventHandle(TransferEvent evt, EventBase eventBase)
        {
            var toActor = GrainFactory.GetGrain <IAccount>(evt.ToId);

            return(toActor.TransferArrived(evt.Amount, new EventUID(eventBase.GetEventId(GrainId.ToString()), eventBase.Timestamp)));
        }
Esempio n. 20
0
        private RemoteClusterActivationResponse ProcessRequestLocal(GrainId grain, string requestClusterId)
        {
            RemoteClusterActivationResponse response;

            //This function will be called only on the Owner silo.
            try
            {
                ActivationAddress address;
                int version;
                GrainDirectoryEntryStatus existingActivationStatus = router.DirectoryPartition.TryGetActivation(grain, out address, out version);


                //Return appropriate protocol response, given current mc status   
                switch (existingActivationStatus)
                {
                    case GrainDirectoryEntryStatus.Invalid:
                        response = RemoteClusterActivationResponse.Pass;
                        break;

                    case GrainDirectoryEntryStatus.Owned:
                        response = new RemoteClusterActivationResponse(ActivationResponseStatus.Failed)
                        {
                            ExistingActivationAddress = new AddressAndTag()
                            {
                                Address = address,
                                VersionTag = version
                            },
                            ClusterId = clusterId,
                            Owned = true
                        };
                        break;

                    case GrainDirectoryEntryStatus.Cached:
                    case GrainDirectoryEntryStatus.RaceLoser:
                        response = RemoteClusterActivationResponse.Pass;
                        break;

                    case GrainDirectoryEntryStatus.RequestedOwnership:
                    case GrainDirectoryEntryStatus.Doubtful:
                        var iWin = MultiClusterUtils.ActivationPrecedenceFunc(grain, clusterId, requestClusterId);
                        if (iWin)
                        {
                            response = new RemoteClusterActivationResponse(ActivationResponseStatus.Failed)
                            {
                                ExistingActivationAddress = new AddressAndTag()
                                {
                                    Address = address,
                                    VersionTag = version
                                },
                                ClusterId = clusterId,
                                Owned = false
                            };
                        }
                        else
                        {
                            response = RemoteClusterActivationResponse.Pass;
                            //update own activation status to race loser.
                            if (existingActivationStatus == GrainDirectoryEntryStatus.RequestedOwnership)
                            {
                                logger.Verbose2("GSIP:Rsp {0} Origin={1} RaceLoser", grain.ToString(), requestClusterId);
                                var success = router.DirectoryPartition.UpdateClusterRegistrationStatus(grain, address.Activation, GrainDirectoryEntryStatus.RaceLoser, GrainDirectoryEntryStatus.RequestedOwnership);
                                if (!success)
                                {
                                    // there was a race. retry.
                                    logger.Verbose2("GSIP:Rsp {0} Origin={1} Retry", grain.ToString(), requestClusterId);
                                    return ProcessRequestLocal(grain, requestClusterId);
                                }
                            }
                        }
                        break;
                    default:
                        throw new InvalidOperationException("Invalid MultiClusterStatus value");

                }
            }
            catch (Exception ex)
            {
                //LOG exception
                response = new RemoteClusterActivationResponse(ActivationResponseStatus.Faulted)
                {
                    ResponseException = ex
                };
            }

            if (logger.IsVerbose)
                logger.Verbose("GSIP:Rsp {0} Origin={1} Result={2}", grain.ToString(), requestClusterId, response);

            return response;
        }
Esempio n. 21
0
        private async Task BatchInputProcessing(List <ConcurrentTransport <Snapshot <PrimaryKey, SnapshotType> > > inputs)
        {
            if (Logger.IsEnabled(LogLevel.Trace))
            {
                Logger.LogTrace("Start batch event processing with id = {0},state version = {1},the number of events = {2}", GrainId.ToString(), CurrentTransactionStartVersion, inputs.Count.ToString());
            }
            await BeginTransaction(defaultTransactionId);

            try
            {
                foreach (var input in inputs)
                {
                    await input.Handler(Snapshot, (evt, uniqueId) =>
                    {
                        TransactionRaiseEvent(evt, uniqueId);
                        input.Executed = true;
                        return(Task.CompletedTask);
                    });
                }
                await CommitTransaction(defaultTransactionId);
                await FinishTransaction(defaultTransactionId);

                foreach (var input in inputs)
                {
                    if (input.Executed)
                    {
                        var completeTask = input.CompletedHandler(true);
                        if (!completeTask.IsCompletedSuccessfully)
                        {
                            await completeTask;
                        }
                    }
                }
            }
            catch (Exception batchEx)
            {
                Logger.LogError(batchEx, batchEx.Message);
                try
                {
                    await RollbackTransaction(defaultTransactionId);
                    await ReTry();
                }
                catch (Exception ex)
                {
                    Logger.LogError(ex, ex.Message);
                    inputs.ForEach(input => input.ExceptionHandler(ex));
                }
            }
            var onCompletedTask = OnBatchInputProcessed();

            if (!onCompletedTask.IsCompletedSuccessfully)
            {
                await onCompletedTask;
            }
            if (Logger.IsEnabled(LogLevel.Trace))
            {
                Logger.LogTrace("Batch events have been processed with id = {0},state version = {1},the number of events = {2}", GrainId.ToString(), CurrentTransactionStartVersion, inputs.Count.ToString());
            }
            async Task ReTry()
            {
                foreach (var input in inputs)
                {
                    try
                    {
                        await input.Handler(Snapshot, async (evt, uniqueId) =>
                        {
                            var result       = await RaiseEvent(evt, uniqueId);
                            var completeTask = input.CompletedHandler(result);
                            if (!completeTask.IsCompletedSuccessfully)
                            {
                                await completeTask;
                            }
                        });
                    }
                    catch (Exception ex)
                    {
                        Logger.LogError(ex, ex.Message);
                        input.ExceptionHandler(ex);
                    }
                }
            }
        }
Esempio n. 22
0
        protected virtual async Task RecoveryState()
        {
            if (Logger.IsEnabled(LogLevel.Trace))
            {
                Logger.LogTrace(LogEventIds.GrainStateRecoveryId, "The state of id = {0} begin to recover", GrainType.FullName, 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 @event in eventList)
                    {
                        Snapshot.Base.IncrementDoingVersion(GrainType);      //标记将要处理的Version
                        EventHandler.Apply(Snapshot, @event);
                        Snapshot.Base.UpdateVersion(@event.Base, GrainType); //更新处理完成的Version
                    }
                    if (eventList.Count < CoreOptions.NumberOfEventsPerRead)
                    {
                        break;
                    }
                }
                ;
                if (Logger.IsEnabled(LogLevel.Trace))
                {
                    Logger.LogTrace(LogEventIds.GrainStateRecoveryId, "The state of id = {0} recovery has been completed ,state version = {1}", GrainId.ToString(), Snapshot.Base.Version);
                }
            }
            catch (Exception ex)
            {
                Logger.LogCritical(LogEventIds.GrainStateRecoveryId, ex, "The state of id = {0} recovery has failed ,state version = {1}", GrainId.ToString(), Snapshot.Base.Version);
                throw;
            }
        }
Esempio n. 23
0
        public override async Task OnActivateAsync()
        {
            if (Logger.IsEnabled(LogLevel.Trace))
            {
                Logger.LogTrace(LogEventIds.GrainActivateId, "Start activation followgrain with id = {0}", GrainId.ToString());
            }
            var dITask = DependencyInjection();

            if (!dITask.IsCompletedSuccessfully)
            {
                await dITask;
            }
            try
            {
                if (ArchiveOptions.On)
                {
                    //加载最后一条归档
                    LastArchive = await ArchiveStorage.GetLatestBrief(GrainId);
                }
                await ReadSnapshotAsync();

                if (FullyActive)
                {
                    await FullActive();
                }
                if (Logger.IsEnabled(LogLevel.Trace))
                {
                    Logger.LogTrace(LogEventIds.GrainActivateId, "Followgrain activation completed with id = {0}", GrainId.ToString());
                }
            }
            catch (Exception ex)
            {
                if (Logger.IsEnabled(LogLevel.Critical))
                {
                    Logger.LogCritical(LogEventIds.FollowGrainActivateId, ex, "Followgrain activation failed with Id = {0}", GrainId.ToString());
                }
                throw;
            }
        }
Esempio n. 24
0
        public override async Task OnDeactivateAsync()
        {
            if (Logger.IsEnabled(LogLevel.Trace))
            {
                Logger.LogTrace(LogEventIds.GrainDeactivateId, "Grain start deactivation with id = {0}", GrainId.ToString());
            }
            var needSaveSnap = Snapshot.Base.Version - SnapshotEventVersion >= CoreOptions.MinSnapshotIntervalVersion;

            try
            {
                if (needSaveSnap)
                {
                    var saveTask = SaveSnapshotAsync(true, true);
                    if (!saveTask.IsCompletedSuccessfully)
                    {
                        await saveTask;
                    }
                    var onDeactivatedTask = OnDeactivated();
                    if (!onDeactivatedTask.IsCompletedSuccessfully)
                    {
                        await onDeactivatedTask;
                    }
                }
                if (ArchiveOptions.On && NewArchive != default)
                {
                    if (NewArchive.EndVersion - NewArchive.StartVersion >= ArchiveOptions.MinIntervalVersion)
                    {
                        var archiveTask = Archive(true);
                        if (!archiveTask.IsCompletedSuccessfully)
                        {
                            await archiveTask;
                        }
                    }
                }
                if (Logger.IsEnabled(LogLevel.Trace))
                {
                    Logger.LogTrace(LogEventIds.GrainDeactivateId, "Grain has been deactivated with id= {0} ,{1}", GrainId.ToString(), needSaveSnap ? "updated snapshot" : "no update snapshot");
                }
            }
            catch (Exception ex)
            {
                if (Logger.IsEnabled(LogLevel.Error))
                {
                    Logger.LogError(LogEventIds.GrainActivateId, ex, "Grain Deactivate failed with Id = {0}", GrainType.FullName, GrainId.ToString());
                }
                throw;
            }
        }
Esempio n. 25
0
 public Task Tell(byte[] bytes)
 {
     var(success, transport) = EventBytesTransport.FromBytesWithNoId(bytes);
     if (success)
     {
         var eventType = TypeContainer.GetType(transport.EventType);
         var data      = Serializer.Deserialize(eventType, transport.EventBytes);
         if (data is IEvent @event)
         {
             var eventBase = EventBase.FromBytes(transport.BaseBytes);
             if (eventBase.Version > Snapshot.Base.Version)
             {
                 var tellTask = Tell(new FullyEvent <PrimaryKey>
                 {
                     StateId = GrainId,
                     Base    = eventBase,
                     Event   = @event
                 });
                 if (!tellTask.IsCompletedSuccessfully)
                 {
                     return(tellTask.AsTask());
                 }
             }
         }
         else
         {
             if (Logger.IsEnabled(LogLevel.Information))
             {
                 Logger.LogInformation(LogEventIds.FollowEventProcessing, "Receive non-event messages, grain Id = {0} ,message type = {1}", GrainId.ToString(), transport.EventType);
             }
         }
     }
     return(Task.CompletedTask);
 }
Esempio n. 26
0
 protected async ValueTask SaveSnapshotAsync(bool force = false, bool isLatest = false)
 {
     if (Snapshot.Base.Version != Snapshot.Base.DoingVersion)
     {
         throw new StateInsecurityException(Snapshot.Base.StateId.ToString(), GrainType, Snapshot.Base.DoingVersion, Snapshot.Base.Version);
     }
     if (Logger.IsEnabled(LogLevel.Trace))
     {
         Logger.LogTrace(LogEventIds.GrainSnapshot, "Start save snapshot  with Id = {0} ,state version = {1}", GrainId.ToString(), Snapshot.Base.Version);
     }
     //如果版本号差超过设置则更新快照
     if (force || (Snapshot.Base.Version - SnapshotEventVersion >= CoreOptions.SnapshotIntervalVersion))
     {
         var oldLatestMinEventTimestamp = Snapshot.Base.LatestMinEventTimestamp;
         try
         {
             var onSaveSnapshotTask = OnStartSaveSnapshot();
             if (!onSaveSnapshotTask.IsCompletedSuccessfully)
             {
                 await onSaveSnapshotTask;
             }
             Snapshot.Base.LatestMinEventTimestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
             Snapshot.Base.IsLatest = isLatest;
             if (SnapshotEventVersion == 0)
             {
                 await SnapshotStorage.Insert(Snapshot);
             }
             else
             {
                 await SnapshotStorage.Update(Snapshot);
             }
             SnapshotEventVersion = Snapshot.Base.Version;
             if (Logger.IsEnabled(LogLevel.Trace))
             {
                 Logger.LogTrace(LogEventIds.GrainSnapshot, "The snapshot of id={0} save completed ,state version = {1}", GrainId.ToString(), Snapshot.Base.Version);
             }
         }
         catch (Exception ex)
         {
             Snapshot.Base.LatestMinEventTimestamp = oldLatestMinEventTimestamp;
             if (Logger.IsEnabled(LogLevel.Critical))
             {
                 Logger.LogCritical(LogEventIds.GrainSnapshot, ex, "The snapshot of id= {0} save failed", GrainId.ToString());
             }
             throw;
         }
     }
 }
        private RemoteClusterActivationResponse ProcessRequestLocal(GrainId grain, string requestClusterId)
        {
            RemoteClusterActivationResponse response;

            //This function will be called only on the Owner silo.
            try
            {
                ActivationAddress address;
                int version;
                GrainDirectoryEntryStatus existingActivationStatus = router.DirectoryPartition.TryGetActivation(grain, out address, out version);


                //Return appropriate protocol response, given current mc status
                switch (existingActivationStatus)
                {
                case GrainDirectoryEntryStatus.Invalid:
                    response = RemoteClusterActivationResponse.Pass;
                    break;

                case GrainDirectoryEntryStatus.Owned:
                    response = new RemoteClusterActivationResponse(ActivationResponseStatus.Failed)
                    {
                        ExistingActivationAddress = new AddressAndTag()
                        {
                            Address    = address,
                            VersionTag = version
                        },
                        ClusterId = clusterId,
                        Owned     = true
                    };
                    break;

                case GrainDirectoryEntryStatus.Cached:
                case GrainDirectoryEntryStatus.RaceLoser:
                    response = RemoteClusterActivationResponse.Pass;
                    break;

                case GrainDirectoryEntryStatus.RequestedOwnership:
                case GrainDirectoryEntryStatus.Doubtful:
                    var iWin = MultiClusterUtils.ActivationPrecedenceFunc(grain, clusterId, requestClusterId);
                    if (iWin)
                    {
                        response = new RemoteClusterActivationResponse(ActivationResponseStatus.Failed)
                        {
                            ExistingActivationAddress = new AddressAndTag()
                            {
                                Address    = address,
                                VersionTag = version
                            },
                            ClusterId = clusterId,
                            Owned     = false
                        };
                    }
                    else
                    {
                        response = RemoteClusterActivationResponse.Pass;
                        //update own activation status to race loser.
                        if (existingActivationStatus == GrainDirectoryEntryStatus.RequestedOwnership)
                        {
                            logger.Trace("GSIP:Rsp {0} Origin={1} RaceLoser", grain.ToString(), requestClusterId);
                            var success = router.DirectoryPartition.UpdateClusterRegistrationStatus(grain, address.Activation, GrainDirectoryEntryStatus.RaceLoser, GrainDirectoryEntryStatus.RequestedOwnership);
                            if (!success)
                            {
                                // there was a race. retry.
                                logger.Trace("GSIP:Rsp {0} Origin={1} Retry", grain.ToString(), requestClusterId);
                                return(ProcessRequestLocal(grain, requestClusterId));
                            }
                        }
                    }
                    break;

                default:
                    throw new InvalidOperationException("Invalid MultiClusterStatus value");
                }
            }
            catch (Exception ex)
            {
                //LOG exception
                response = new RemoteClusterActivationResponse(ActivationResponseStatus.Faulted)
                {
                    ResponseException = ex
                };
            }

            if (logger.IsEnabled(LogLevel.Debug))
            {
                logger.Debug("GSIP:Rsp {0} Origin={1} Result={2}", grain.ToString(), requestClusterId, response);
            }

            return(response);
        }
Esempio n. 28
0
        protected virtual async Task <bool> RaiseEvent(IEvent @event, EventUID uniqueId = null)
        {
            if (Logger.IsEnabled(LogLevel.Trace))
            {
                Logger.LogTrace(LogEventIds.GrainSnapshot, "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
                {
                    EventType  = @event.GetType().FullName,
                    ActorId    = Snapshot.Base.StateId,
                    EventBytes = Serializer.SerializeToBytes(@event),
                    BaseBytes  = fullyEvent.Base.GetBytes()
                };
                if (await EventStorage.Append(new SaveTransport <PrimaryKey>(fullyEvent, 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;
                    }
                    var handlers = FollowUnit.GetAllEventHandlers();
                    if (handlers.Count > 0)
                    {
                        try
                        {
                            if (CoreOptions.PriorityAsyncEventBus)
                            {
                                try
                                {
                                    var publishTask = EventBusProducer.Publish(bytesTransport.GetBytes(), GrainId.ToString());
                                    if (!publishTask.IsCompletedSuccessfully)
                                    {
                                        await publishTask;
                                    }
                                }
                                catch (Exception ex)
                                {
                                    if (Logger.IsEnabled(LogLevel.Error))
                                    {
                                        Logger.LogError(LogEventIds.GrainRaiseEvent, ex, "EventBus error,state  Id ={0}, version ={1}", GrainId.ToString(), Snapshot.Base.Version);
                                    }
                                    //当消息队列出现问题的时候同步推送
                                    await Task.WhenAll(handlers.Select(func => func(bytesTransport.GetBytes())));
                                }
                            }
                            else
                            {
                                try
                                {
                                    await Task.WhenAll(handlers.Select(func => func(bytesTransport.GetBytes())));
                                }
                                catch (Exception ex)
                                {
                                    if (Logger.IsEnabled(LogLevel.Error))
                                    {
                                        Logger.LogError(LogEventIds.GrainRaiseEvent, ex, "EventBus error,state  Id ={0}, version ={1}", GrainId.ToString(), Snapshot.Base.Version);
                                    }
                                    //当消息队列出现问题的时候异步推送
                                    var publishTask = EventBusProducer.Publish(bytesTransport.GetBytes(), GrainId.ToString());
                                    if (!publishTask.IsCompletedSuccessfully)
                                    {
                                        await publishTask;
                                    }
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            if (Logger.IsEnabled(LogLevel.Error))
                            {
                                Logger.LogError(LogEventIds.GrainRaiseEvent, ex, "EventBus error,state  Id ={0}, version ={1}", GrainId.ToString(), Snapshot.Base.Version);
                            }
                        }
                    }
                    if (Logger.IsEnabled(LogLevel.Trace))
                    {
                        Logger.LogTrace(LogEventIds.GrainRaiseEvent, "Raise event successfully, grain Id= {0} and state version = {1}}", GrainId.ToString(), Snapshot.Base.Version);
                    }
                    return(true);
                }
                else
                {
                    if (Logger.IsEnabled(LogLevel.Information))
                    {
                        Logger.LogInformation(LogEventIds.GrainRaiseEvent, "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;
                    }
                    Snapshot.Base.DecrementDoingVersion();//还原doing Version
                }
            }
            catch (Exception ex)
            {
                if (Logger.IsEnabled(LogLevel.Error))
                {
                    Logger.LogError(LogEventIds.GrainRaiseEvent, ex, "Raise event produces errors, state Id = {0}, version ={1},event type = {2},event = {3}", GrainId.ToString(), Snapshot.Base.Version, @event.GetType().FullName, Serializer.SerializeToString(@event));
                }
                await RecoveryState();//还原状态

                throw;
            }
            return(false);
        }
Esempio n. 29
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.LogError(ex, "Transaction failed: {0}->{1}->{2}", GrainType.FullName, GrainId.ToString(), transactionId);
                    throw;
                }
            }
        }
Esempio n. 30
0
 /// <summary>
 /// 发送无状态更改的消息到消息队列
 /// </summary>
 /// <returns></returns>
 protected async ValueTask Publish <T>(T msg, string hashKey = null)
 {
     if (Logger.IsEnabled(LogLevel.Trace))
     {
         Logger.LogTrace(LogEventIds.MessagePublish, "Start publishing, grain Id= {0}, message type = {1},message = {2},hashkey={3}", GrainId.ToString(), msg.GetType().FullName, Serializer.SerializeToString(msg), hashKey);
     }
     if (string.IsNullOrEmpty(hashKey))
     {
         hashKey = GrainId.ToString();
     }
     try
     {
         var wrapper     = new CommonTransport(msg.GetType().FullName, Serializer.SerializeToBytes(msg));
         var pubLishTask = EventBusProducer.Publish(wrapper.GetBytes(), hashKey);
         if (!pubLishTask.IsCompletedSuccessfully)
         {
             await pubLishTask;
         }
     }
     catch (Exception ex)
     {
         if (Logger.IsEnabled(LogLevel.Error))
         {
             Logger.LogError(LogEventIds.MessagePublish, ex, "Publish message errors, grain Id= {0}, message type = {1},message = {2},hashkey={3}", GrainId.ToString(), msg.GetType().FullName, Serializer.SerializeToString(msg), hashKey);
         }
         throw;
     }
 }
Esempio n. 31
0
        private GrainId RoundTripGrainIdToParsable(GrainId input)
        {
            string str = input.ToString();

            return(GrainId.Parse(str));
        }
Esempio n. 32
0
        protected async Task BeginTransaction(long transactionId)
        {
            if (Logger.IsEnabled(LogLevel.Trace))
            {
                Logger.LogTrace("Begin transaction with grainid {0} and transactionId {1},transaction start state version {2}", GrainId.ToString(), transactionId, CurrentTransactionStartVersion.ToString());
            }
            if (TransactionStartMilliseconds != 0 &&
                DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - TransactionStartMilliseconds > CoreOptions.TransactionMillisecondsTimeout)
            {
                if (await TransactionTimeoutLock.WaitAsync(CoreOptions.TransactionMillisecondsTimeout))
                {
                    try
                    {
                        if (TransactionStartMilliseconds != 0 &&
                            DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - TransactionStartMilliseconds > CoreOptions.TransactionMillisecondsTimeout)
                        {
                            await RollbackTransaction(CurrentTransactionId);//事务超时自动回滚

                            Logger.LogError("Transaction timeout, automatic rollback,grain id = {1}", GrainId.ToString());
                        }
                    }
                    finally
                    {
                        TransactionTimeoutLock.Release();
                    }
                }
            }
            if (await TransactionSemaphore.WaitAsync(CoreOptions.TransactionMillisecondsTimeout))
            {
                try
                {
                    SnapshotCheck();
                    CurrentTransactionStartVersion = Snapshot.Base.Version + 1;
                    CurrentTransactionId           = transactionId;
                    TransactionStartMilliseconds   = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
                }
                catch
                {
                    TransactionSemaphore.Release();
                    throw;
                }
            }
            else
            {
                throw new BeginTxTimeoutException(GrainId.ToString(), transactionId, GrainType);
            }
        }
Esempio n. 33
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;
                 }
                 transport.BytesTransport = new EventBytesTransport(
                     TypeContainer.GetTypeCode(transport.FullyEvent.Event.GetType()),
                     GrainId,
                     transport.FullyEvent.Base.GetBytes(),
                     Serializer.SerializeToBytes(transport.FullyEvent.Event)
                     );
             }
             await EventStorage.TransactionBatchAppend(WaitingForTransactionTransports);
         }
         catch (Exception ex)
         {
             Logger.LogError(ex, "Commit transaction failed, grain Id = {1}", GrainId.ToString());
             throw;
         }
     }
 }
Esempio n. 34
0
        public async Task RollbackTransaction(long transactionId)
        {
            if (Logger.IsEnabled(LogLevel.Trace))
            {
                Logger.LogTrace("Start rollback 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 (CurrentTransactionId == transactionId && CurrentTransactionStartVersion != -1 && Snapshot.Base.Version >= CurrentTransactionStartVersion)
            {
                try
                {
                    if (BackupSnapshot.Base.Version == CurrentTransactionStartVersion - 1)
                    {
                        Snapshot = new Snapshot <PrimaryKey, StateType>(GrainId)
                        {
                            Base  = BackupSnapshot.Base.Clone(),
                            State = BackupSnapshot.State.Clone()
                        };
                    }
                    else
                    {
                        if (BackupSnapshot.Base.Version >= CurrentTransactionStartVersion)
                        {
                            await EventStorage.DeleteEnd(Snapshot.Base.StateId, CurrentTransactionStartVersion, Snapshot.Base.LatestMinEventTimestamp);
                        }
                        await RecoverySnapshot();
                    }

                    WaitingForTransactionTransports.Clear();
                    RestoreTransactionTemporaryState();
                    TransactionSemaphore.Release();
                    if (Logger.IsEnabled(LogLevel.Trace))
                    {
                        Logger.LogTrace("Rollback transaction successfully with id = {0},state version = {1}", GrainId.ToString(), Snapshot.Base.Version.ToString());
                    }
                }
                catch (Exception ex)
                {
                    Logger.LogCritical(ex, "Rollback transaction failed with Id = {1}", GrainId.ToString());
                    throw;
                }
            }
        }
Esempio n. 35
0
 /// <summary>
 /// Adds a new activation to the directory partition
 /// </summary>
 /// <param name="grain"></param>
 /// <param name="activation"></param>
 /// <param name="silo"></param>
 /// <returns>The version associated with this directory mapping</returns>
 internal virtual int AddActivation(GrainId grain, ActivationId activation, SiloAddress silo)
 {
     if (!IsValidSilo(silo))
     {
         return GrainInfo.NO_ETAG;
     }
     lock (lockable)
     {
         if (!partitionData.ContainsKey(grain))
         {
             partitionData[grain] = new GrainInfo();
         }
         partitionData[grain].AddActivation(activation, silo);
     }
     if (log.IsVerbose3) log.Verbose3("Adding activation for grain {0}", grain.ToString());
     return partitionData[grain].VersionTag;
 }
Esempio n. 36
0
 /// <summary>
 /// 事务性事件提交
 /// 使用该函数前必须开启事务,不然会出现异常
 /// </summary>
 /// <param name="event"></param>
 /// <param name="eUID"></param>
 protected void TxRaiseEvent(IEvent @event, EventUID eUID = null)
 {
     if (Logger.IsEnabled(LogLevel.Trace))
     {
         Logger.LogTrace("Start transactionRaiseEvent, 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), eUID);
     }
     try
     {
         if (CurrentTransactionStartVersion == -1)
         {
             throw new UnopenedTransactionException(GrainId.ToString(), GrainType, nameof(TxRaiseEvent));
         }
         Snapshot.Base.IncrementDoingVersion(GrainType);//标记将要处理的Version
         var fullyEvent = new FullyEvent <PrimaryKey>
         {
             StateId = GrainId,
             Event   = @event,
             Base    = new EventBase
             {
                 Version = Snapshot.Base.Version + 1
             }
         };
         string unique = default;
         if (eUID == default)
         {
             fullyEvent.Base.Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
             unique = fullyEvent.GetEventId();
         }
         else
         {
             fullyEvent.Base.Timestamp = eUID.Timestamp;
             unique = eUID.UID;
         }
         WaitingForTransactionTransports.Add(new EventTransport <PrimaryKey>(fullyEvent, unique, fullyEvent.StateId.ToString()));
         SnapshotHandler.Apply(Snapshot, fullyEvent);
         Snapshot.Base.UpdateVersion(fullyEvent.Base, GrainType);//更新处理完成的Version
     }
     catch (Exception ex)
     {
         Logger.LogCritical(ex, "Grain Id = {0},event type = {1} and event = {2}", GrainId.ToString(), @event.GetType().FullName, Serializer.SerializeToString(@event));
         Snapshot.Base.DecrementDoingVersion();//还原doing Version
         throw;
     }
 }
Esempio n. 37
0
 /// <summary>
 /// Removes the grain (and, effectively, all its activations) from the diretcory
 /// </summary>
 /// <param name="grain"></param>
 internal void RemoveGrain(GrainId grain)
 {
     lock (lockable)
     {
         partitionData.Remove(grain);
     }
     if (log.IsVerbose3) log.Verbose3("Removing grain {0}", grain.ToString());
 }
Esempio n. 38
0
        /// <summary>
        /// Adds a new activation to the directory partition
        /// </summary>
        /// <param name="grain"></param>
        /// <param name="activation"></param>
        /// <param name="silo"></param>
        /// <returns>The version associated with this directory mapping</returns>
        internal virtual int AddActivation(GrainId grain, ActivationId activation, SiloAddress silo)
        {
            if (!IsValidSilo(silo))
            {
                return GrainInfo.NO_ETAG;
            }

            IGrainInfo grainInfo;
            lock (lockable)
            {
                if (!partitionData.TryGetValue(grain, out grainInfo))
                {
                    partitionData[grain] = grainInfo = new GrainInfo();
                }

                grainInfo.AddActivation(activation, silo);
            }

            if (log.IsVerbose3) log.Verbose3("Adding activation for grain {0}", grain.ToString());
            return grainInfo.VersionTag;
        }