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); }
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)); } } }
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); } }
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); }
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); } }
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);
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} "); }
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); } } } }
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)); }))); } }
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; })); }
/// <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)); }
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); } }
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); }
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(); } }); }
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); }
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); } } }
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); }
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); } }
public BatchAppendTransport(IFullyEvent <PrimaryKey> evt, EventBytesTransport bytesTransport, string uniqueId = null) { Event = evt; UniqueId = uniqueId; BytesTransport = bytesTransport; }
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; } } }
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; } } } }))); } }
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; } } }
protected virtual ValueTask OnRaiseSuccessed(IFullyEvent <PrimaryKey> @event, EventBytesTransport bytesTransport) { if (ArchiveOptions.On) { return(EventArchive(@event)); } return(Consts.ValueTaskDone); }
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); }