Example #1
0
 public Task OnNext(Immutable <byte[]> bytes)
 {
     var(success, transport) = EventBytesTransport.FromBytesWithNoId(bytes.Value);
     if (success)
     {
         var eventType = TypeContainer.GetType(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());
                 }
             }
         }
         else
         {
             if (Logger.IsEnabled(LogLevel.Information))
             {
                 Logger.LogInformation("Non-event messages:{0}({1})", eventType, Serializer.Serialize(data));
             }
         }
     }
     return(Task.CompletedTask);
 }
Example #2
0
        public void Observer()
        {
            if (!typeof(IPoleEventHandler).IsAssignableFrom(EventHandlerType))
            {
                throw new NotSupportedException($"{EventHandlerType.FullName} must inheritance from PoleEventHandler");
            }
            eventHandler = EventHandler;
            //内部函数
            Task EventHandler(byte[] bytes)
            {
                var(success, transport) = EventBytesTransport.FromBytes(bytes);
                if (!success)
                {
                    if (Logger.IsEnabled(LogLevel.Error))
                    {
                        Logger.LogError($" EventId:{nameof(EventBytesTransport.EventId)} is not a event");
                    }
                }

                // 批量处理的时候 grain Id 取第一个 event的id
                using (var scope = serviceProvider.CreateScope())
                {
                    var eventHandlerInstance = scope.ServiceProvider.GetRequiredService(EventHandlerType);
                    var serializer           = scope.ServiceProvider.GetRequiredService <ISerializer>() as ISerializer;
                    var eventTypeFinder      = scope.ServiceProvider.GetRequiredService <IEventTypeFinder>() as IEventTypeFinder;
                    var loggerFactory        = scope.ServiceProvider.GetRequiredService <ILoggerFactory>() as ILoggerFactory;
                    var logger = loggerFactory.CreateLogger(EventHandlerType);
                    return(GetObserver(EventHandlerType)(eventHandlerInstance, transport, serializer, eventTypeFinder, logger, EventHandlerType));
                }
            }
        }
Example #3
0
        public void Observer(string group, Type observerType)
        {
            var funcs = GetEventHandlers(group);

            funcs.Add(func);
            eventHandlers.Add(func);
            observerVersionHandlers.Add((actorId, version) => GetVersion(observerType, actorId).GetAndSaveVersion(version));
            //内部函数
            Task func(byte[] bytes)
            {
                var(success, actorId) = EventBytesTransport.GetActorId <PrimaryKey>(bytes);
                if (success)
                {
                    if (typeof(IObserver).IsAssignableFrom(observerType))
                    {
                        return(GetObserver(observerType, actorId).OnNext(new Immutable <byte[]>(bytes)));
                    }
                    else if (typeof(IConcurrentObserver).IsAssignableFrom(observerType))
                    {
                        return(GetConcurrentObserver(observerType, actorId).OnNext(new Immutable <byte[]>(bytes)));
                    }
                    else
                    {
                        throw new NotSupportedException($"{observerType.FullName} must inheritance from 'IConcurrentObserver' or 'IObserver'");
                    }
                }
                return(Task.CompletedTask);
            }
        }
Example #4
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("Receive non-event messages, grain Id = {0} ,message type = {1}", GrainId.ToString(), transport.EventType);
             }
         }
     }
     return(Task.CompletedTask);
 }
Example #5
0
        public ObserverUnit <PrimaryKey> UnreliableObserver(string group, Func <IServiceProvider, IFullyEvent <PrimaryKey>, ValueTask> handler)
        {
            var funcs = GetEventHandlers(group);

            funcs.Add(func);
            eventHandlers.Add(func);
            return(this);

            //内部函数
            Task func(byte[] bytes)
            {
                var(success, transport) = EventBytesTransport.FromBytes <PrimaryKey>(bytes);
                if (success)
                {
                    var data = serializer.Deserialize(TypeContainer.GetType(transport.EventTypeCode), transport.EventBytes);
                    if (data is IEvent @event && transport.GrainId is PrimaryKey actorId)
                    {
                        var eventBase = EventBase.FromBytes(transport.BaseBytes);
                        var tellTask  = handler(serviceProvider, new FullyEvent <PrimaryKey>
                        {
                            StateId = actorId,
                            Base    = eventBase,
                            Event   = @event
                        });
                        if (!tellTask.IsCompletedSuccessfully)
                        {
                            return(tellTask.AsTask());
                        }
                    }
                }
                return(Task.CompletedTask);
            }
        }
Example #6
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 = TypeContainer.GetType(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);
Example #7
0
        private async Task ExecuteCore(List <EventEntity> eventEntities)
        {
            logger.LogTrace($"Begin ExecuteCore Count:{eventEntities.Count} ");
            var events = eventEntities.Select(entity =>
            {
                var eventContentBytes = Encoding.UTF8.GetBytes(entity.Content);
                var bytesTransport    = new EventBytesTransport(entity.Name, entity.Id, eventContentBytes);
                var bytes             = bytesTransport.GetBytes();
                var targetName        = producerContainer.GetTargetName(entity.Name);
                entity.StatusName     = nameof(EventStatus.Published);
                entity.ExpiresAt      = DateTime.UtcNow.AddSeconds(options.PublishedEventsExpiredAfterSeconds);
                return(targetName, bytes);
            });

            eventEntities.ForEach(entity =>
            {
                entity.StatusName = nameof(EventStatus.Published);
                entity.ExpiresAt  = DateTime.UtcNow.AddSeconds(options.PublishedEventsExpiredAfterSeconds);
            });
            logger.LogTrace($"Begin BulkPublish {DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss")} ");
            await producer.BulkPublish(events);

            logger.LogTrace($"Begin BulkPublish {DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss")} ");
            if (eventEntities.Count > 10)
            {
                await eventStorage.BulkChangePublishStateAsync(eventEntities);
            }
            else
            {
                await eventStorage.ChangePublishStateAsync(eventEntities);
            }

            logger.LogTrace($"End ExecuteCore {DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss")}  Count:{eventEntities.Count} ");
        }
Example #8
0
 public async Task OnNext(Immutable <byte[]> bytes)
 {
     var(success, transport) = EventBytesTransport.FromBytesWithNoId(bytes.Value);
     if (success)
     {
         var data = Serializer.Deserialize(TypeContainer.GetType(transport.EventTypeCode), transport.EventBytes);
         if (data is IEvent @event)
         {
             var eventBase = EventBase.FromBytes(transport.BaseBytes);
             if (eventBase.Version > Snapshot.Version)
             {
                 if (concurrent)
                 {
                     var input = new AsyncInputEvent <IFullyEvent <PrimaryKey>, bool>(new FullyEvent <PrimaryKey>
                     {
                         StateId = GrainId,
                         Base    = eventBase,
                         Event   = @event
                     });
                     var writeTask = ConcurrentChannel.WriteAsync(input);
                     if (!writeTask.IsCompletedSuccessfully)
                     {
                         await writeTask;
                     }
                     if (!writeTask.Result)
                     {
                         var ex = new ChannelUnavailabilityException(GrainId.ToString(), GrainType);
                         Logger.LogError(ex, ex.Message);
                         throw ex;
                     }
                     await input.TaskSource.Task;
                 }
                 else
                 {
                     var tellTask = Tell(new FullyEvent <PrimaryKey>
                     {
                         StateId = GrainId,
                         Base    = eventBase,
                         Event   = @event
                     });
                     if (!tellTask.IsCompletedSuccessfully)
                     {
                         await tellTask;
                     }
                 }
             }
         }
         else
         {
             if (Logger.IsEnabled(LogLevel.Information))
             {
                 Logger.LogInformation("Receive non-event messages, grain Id = {0} ,message type = {1}", GrainId.ToString(), transport.EventTypeCode);
             }
         }
     }
 }
Example #9
0
        public void Observer(string group, Type observerType)
        {
            if (!typeof(IObserver).IsAssignableFrom(observerType))
            {
                throw new NotSupportedException($"{observerType.FullName} must inheritance from IObserver");
            }
            GetEventHandlers(group).Add(EventHandler);
            GetBatchEventHandlers(group).Add(BatchEventHandler);
            eventHandlers.Add(EventHandler);
            batchEventHandlers.Add(BatchEventHandler);
            observerVersionHandlers.Add((actorId, version) => GetObserver(observerType, actorId).GetAndSaveVersion(version));
            observerSyncHandlers.Add((actorId, version) => GetObserver(observerType, actorId).SyncFromObservable(version));
            observerResetHandlers.Add((actorId) => GetObserver(observerType, actorId).Reset());
            //内部函数
            Task EventHandler(byte[] bytes)
            {
                var(success, actorId) = EventBytesTransport.GetActorId <PrimaryKey>(bytes);
                if (success)
                {
                    return(GetObserver(observerType, actorId).OnNext(new Immutable <byte[]>(bytes)));
                }
                else
                {
                    if (Logger.IsEnabled(LogLevel.Error))
                    {
                        Logger.LogError($"{nameof(EventBytesTransport.GetActorId)} failed");
                    }
                }
                return(Task.CompletedTask);
            }

            Task BatchEventHandler(List <byte[]> list)
            {
                var groups = list.Select(bytes =>
                {
                    var(success, GrainId) = EventBytesTransport.GetActorId <PrimaryKey>(bytes);
                    if (!success)
                    {
                        if (Logger.IsEnabled(LogLevel.Error))
                        {
                            Logger.LogError($"{nameof(EventBytesTransport.GetActorId)} failed");
                        }
                    }
                    return(success, GrainId, bytes);
                }).Where(o => o.success).GroupBy(o => o.GrainId);

                return(Task.WhenAll(groups.Select(kv =>
                {
                    var items = kv.Select(item => item.bytes).ToList();
                    return GetObserver(observerType, kv.Key).OnNext(new Immutable <List <byte[]> >(items));
                })));
            }
        }
Example #10
0
 public Task <bool> Append(IFullyEvent <PrimaryKey> fullyEvent, EventBytesTransport bytesTransport, string unique)
 {
     return(Task.Run(async() =>
     {
         var wrap = new AsyncInputEvent <BatchAppendTransport <PrimaryKey>, bool>(new BatchAppendTransport <PrimaryKey>(fullyEvent, bytesTransport, unique));
         var writeTask = mpscChannel.WriteAsync(wrap);
         if (!writeTask.IsCompletedSuccessfully)
         {
             await writeTask;
         }
         return await wrap.TaskSource.Task;
     }));
 }
Example #11
0
 /// <summary>
 /// 防止对象在Snapshot和BackupSnapshot中互相干扰,所以反序列化一个全新的Event对象给BackupSnapshot
 /// </summary>
 /// <param name="fullyEvent">事件本体</param>
 /// <param name="bytes">事件序列化之后的二进制数据</param>
 protected override ValueTask OnRaised(FullyEvent <PrimaryKey> fullyEvent, EventBytesTransport transport)
 {
     if (BackupSnapshot.Base.Version + 1 == fullyEvent.Base.Version)
     {
         var copiedEvent = new FullyEvent <PrimaryKey>
         {
             Event = Serializer.Deserialize(transport.EventBytes, fullyEvent.Event.GetType()) as IEvent,
             Base  = EventBase.FromBytes(transport.BaseBytes)
         };
         SnapshotHandler.Apply(BackupSnapshot, copiedEvent);
         BackupSnapshot.Base.FullUpdateVersion(copiedEvent.Base, GrainType);//更新处理完成的Version
     }
     //父级涉及状态归档
     return(base.OnRaised(fullyEvent, transport));
 }
Example #12
0
        public async Task Invoke(EventBytesTransport transport, ISerializer serializer, IEventTypeFinder eventTypeFinder, ILogger logger, Type eventHandlerType)
        {
            var eventType = eventTypeFinder.FindType(transport.EventTypeCode);
            var @event    = (TEvent)serializer.Deserialize(transport.EventBytes, eventType);

            if (this is IPoleEventHandler <TEvent> handler)
            {
                var   handleTasks = handler.EventHandle(@event);
                await handleTasks;
                logger.LogTrace("Invoke completed: {0}->{1}->{2}", eventHandlerType.FullName, nameof(handler.EventHandle), serializer.Serialize(@event));
                return;
            }
            else
            {
                throw new EventHandlerImplementedNotRightException(nameof(handler.EventHandle), eventType.Name, this.GetType().FullName);
            }
        }
Example #13
0
        public StringFollowUnit <E> BindConcurrentFlow <F>(string followType)
            where F : IConcurrentFollow, IGrainWithStringKey
        {
            var funcs = GetEventHandlers(followType);

            funcs.Add((byte[] bytes) =>
            {
                var(success, actorId) = EventBytesTransport.GetActorIdWithString(bytes);
                if (success)
                {
                    return(serviceProvider.GetService <IClusterClient>().GetGrain <F>(actorId).ConcurrentTell(bytes));
                }
                return(Task.CompletedTask);
            });
            followVersionHandlers.Add((stateId, version) => serviceProvider.GetService <IClusterClient>().GetGrain <F>(stateId).GetAndSaveVersion(version));
            return(this);
        }
Example #14
0
        public async Task CompeleteAsync(CancellationToken cancellationToken = default)
        {
            await bus.Transaction.CommitAsync();

            var bufferedEvents = bus.PrePublishEventBuffer.ToList();

            bufferedEvents.ForEach(async @event =>
            {
                var eventType         = eventTypeFinder.FindType(@event.Name);
                var eventContentBytes = Encoding.UTF8.GetBytes(@event.Content);
                var bytesTransport    = new EventBytesTransport(@event.Name, @event.Id, eventContentBytes);
                var bytes             = bytesTransport.GetBytes();
                var result            = await eventBuffer.AddAndRun(@event);
                if (!result)
                {
                    throw new AddEventToEventBufferException();
                }
            });
        }
Example #15
0
        public LongFollowUnit Flow <F>(string followType)
            where F : IFollow, IGrainWithIntegerKey
        {
            var funcs = GetEventHandlers(followType);

            Task func(byte[] bytes)
            {
                var(success, actorId) = EventBytesTransport.GetActorIdWithLong(bytes);
                if (success)
                {
                    return(serviceProvider.GetService <IClusterClient>().GetGrain <F>(actorId).Tell(bytes));
                }
                return(Task.CompletedTask);
            }

            funcs.Add(func);
            eventHandlers.Add(func);
            followVersionHandlers.Add((stateId, version) => serviceProvider.GetService <IClusterClient>().GetGrain <F>(stateId).GetAndSaveVersion(version));
            return(this);
        }
Example #16
0
 public async Task ConcurrentTell(byte[] bytes)
 {
     var(success, transport) = EventBytesTransport.FromBytesWithNoId(bytes);
     if (success)
     {
         var data = Serializer.Deserialize(TypeContainer.GetType(transport.EventType), transport.EventBytes);
         if (data is IEvent @event)
         {
             var eventBase = EventBase.FromBytes(transport.BaseBytes);
             if (eventBase.Version > Snapshot.Version)
             {
                 var writeTask = ConcurrentChannel.WriteAsync(new DataAsyncWrapper <IFullyEvent <PrimaryKey>, bool>(new FullyEvent <PrimaryKey>
                 {
                     StateId = GrainId,
                     Base    = eventBase,
                     Event   = @event
                 }));
                 if (!writeTask.IsCompletedSuccessfully)
                 {
                     await writeTask;
                 }
                 if (!writeTask.Result)
                 {
                     var ex = new ChannelUnavailabilityException(GrainId.ToString(), GrainType);
                     if (Logger.IsEnabled(LogLevel.Error))
                     {
                         Logger.LogError(LogEventIds.TransactionGrainCurrentInput, ex, ex.Message);
                     }
                     throw ex;
                 }
             }
         }
         else
         {
             if (Logger.IsEnabled(LogLevel.Information))
             {
                 Logger.LogInformation(LogEventIds.FollowEventProcessing, "Receive non-event messages, grain Id = {0} ,message type = {1}", GrainId.ToString(), transport.EventType);
             }
         }
     }
 }
        public async Task ProcessInternal()
        {
            var now = DateTime.UtcNow;

            var pendingMessages = await eventStorage.GetEventsOfNeedRetry();

            if (logger.IsEnabled(LogLevel.Debug))
            {
                logger.LogDebug($"{nameof(PendingMessageRetryProcessor)}  pendingMessages count:{pendingMessages.Count()}");
            }
            foreach (var pendingMessage in pendingMessages)
            {
                var eventContentBytes = Encoding.UTF8.GetBytes(pendingMessage.Content);
                var bytesTransport    = new EventBytesTransport(pendingMessage.Name, pendingMessage.Id, eventContentBytes);
                var bytes             = bytesTransport.GetBytes();
                if (pendingMessage.Retries > options.MaxFailedRetryCount)
                {
                    pendingMessage.StatusName = nameof(EventStatus.Failed);
                    continue;
                }
                pendingMessage.Retries++;
                var targetName = producerContainer.GetTargetName(pendingMessage.Name);
                await producer.Publish(targetName, bytes);

                pendingMessage.StatusName = nameof(EventStatus.Published);
                pendingMessage.ExpiresAt  = DateTime.UtcNow.AddSeconds(options.PublishedEventsExpiredAfterSeconds);
            }
            if (pendingMessages.Count() > 0)
            {
                if (pendingMessages.Count() > 10)
                {
                    await eventStorage.BulkChangePublishStateAsync(pendingMessages);
                }
                else
                {
                    await eventStorage.ChangePublishStateAsync(pendingMessages);
                }
            }
        }
Example #18
0
 public Task OnNext(Immutable <byte[]> bytes)
 {
     var(success, transport) = EventBytesTransport.FromBytesWithNoId(bytes.Value);
     if (success)
     {
         var eventType = TypeContainer.GetType(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);
 }
Example #19
0
        public void Observer(string group, Type observerType)
        {
            var funcs = GetEventHandlers(group);

            funcs.Add(func);
            eventHandlers.Add(func);
            observerVersionHandlers.Add((actorId, version) => GetObserver(observerType, actorId).GetAndSaveVersion(version));
            //内部函数
            Task func(byte[] bytes)
            {
                var(success, actorId) = EventBytesTransport.GetActorId <PrimaryKey>(bytes);
                if (success)
                {
                    var observer = GetObserver(observerType, actorId);
                    if (observer is IConcurrentObserver concurrentObserver)
                    {
                        return(concurrentObserver.ConcurrentOnNext(new Immutable <byte[]>(bytes)));
                    }
                    return(observer.OnNext(new Immutable <byte[]>(bytes)));
                }
                return(Task.CompletedTask);
            }
        }
Example #20
0
 public BatchAppendTransport(IFullyEvent <PrimaryKey> evt, EventBytesTransport bytesTransport, string uniqueId = null)
 {
     Event          = evt;
     UniqueId       = uniqueId;
     BytesTransport = bytesTransport;
 }
Example #21
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;
                    }
                }
            }
Example #22
0
        public ObserverUnit <PrimaryKey> UnreliableObserver(
            string group,
            Func <IServiceProvider,
                  FullyEvent <PrimaryKey>, ValueTask> handler)
        {
            GetEventHandlers(group).Add(EventHandler);
            GetBatchEventHandlers(group).Add(BatchEventHandler);
            eventHandlers.Add(EventHandler);
            batchEventHandlers.Add(BatchEventHandler);
            return(this);

            //内部函数
            Task EventHandler(byte[] bytes)
            {
                var(success, transport) = EventBytesTransport.FromBytes <PrimaryKey>(bytes);
                if (success)
                {
                    var data = serializer.Deserialize(transport.EventBytes, typeFinder.FindType(transport.EventTypeCode));
                    if (data is IEvent @event && transport.GrainId is PrimaryKey actorId)
                    {
                        var eventBase = EventBase.FromBytes(transport.BaseBytes);
                        var tellTask  = handler(serviceProvider, new FullyEvent <PrimaryKey>
                        {
                            StateId = actorId,
                            Base    = eventBase,
                            Event   = @event
                        });
                        if (!tellTask.IsCompletedSuccessfully)
                        {
                            return(tellTask.AsTask());
                        }
                    }
                }
                return(Task.CompletedTask);
            }

            Task BatchEventHandler(List <byte[]> list)
            {
                var groups =
                    list.Select(b => EventBytesTransport.FromBytes <PrimaryKey>(b))
                    .Where(o => o.success)
                    .Select(o => o.transport)
                    .GroupBy(o => o.GrainId);

                return(Task.WhenAll(groups.Select(async kv =>
                {
                    foreach (var transport in kv)
                    {
                        var data = serializer.Deserialize(transport.EventBytes, typeFinder.FindType(transport.EventTypeCode));
                        if (data is IEvent @event && transport.GrainId is PrimaryKey actorId)
                        {
                            var eventBase = EventBase.FromBytes(transport.BaseBytes);
                            var tellTask = handler(serviceProvider, new FullyEvent <PrimaryKey>
                            {
                                StateId = actorId,
                                Base = eventBase,
                                Event = @event
                            });
                            if (!tellTask.IsCompletedSuccessfully)
                            {
                                await tellTask;
                            }
                        }
                    }
                })));
            }
        }
Example #23
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;
                    }
                }
            }
Example #24
0
 protected virtual ValueTask OnRaiseSuccessed(IFullyEvent <PrimaryKey> @event, EventBytesTransport bytesTransport)
 {
     if (ArchiveOptions.On)
     {
         return(EventArchive(@event));
     }
     return(Consts.ValueTaskDone);
 }
Example #25
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
                {
                    EventType  = @event.GetType().FullName,
                    GrainId    = Snapshot.Base.StateId,
                    EventBytes = Serializer.SerializeToBytes(@event),
                    BaseBytes  = fullyEvent.Base.GetBytes()
                };
                if (await EventStorage.Append(fullyEvent, bytesTransport, uniqueId.UID))
                {
                    Snapshot.Apply(EventHandler, 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)
                                {
                                    Logger.LogError(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)
                                {
                                    Logger.LogError(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)
                        {
                            Logger.LogError(ex, "EventBus error,state  Id ={0}, version ={1}", GrainId.ToString(), Snapshot.Base.Version);
                        }
                    }
                    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
                {
                    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;
                    }
                    Snapshot.Base.DecrementDoingVersion();//还原doing Version
                }
            }
            catch (Exception ex)
            {
                if (Logger.IsEnabled(LogLevel.Error))
                {
                    Logger.LogError(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 RecoverySnapshot();//还原状态

                throw;
            }
            return(false);
        }