private byte[] ConvertToBytes(EventDocumentDto document, long id) { var meta = new EventMeta { Version = document.Version, Timestamp = document.Timestamp, FlowId = document.FlowId }; using var baseBytes = EventExtensions.ConvertToBytes(meta); var transUnit = new EventTransUnit(document.Name, id, baseBytes.AsSpan(), Encoding.UTF8.GetBytes(document.Data)); using var buffer = EventConverter.ConvertToBytes(transUnit); return(buffer.ToArray()); }
public EventBufferUnit(EventUnit <TPrimaryKey> eventUnit, string flowId, IEventTypeContainer eventTypeContainer, ISerializer serializer) { var evtType = eventUnit.Event.GetType(); if (!eventTypeContainer.TryGet(evtType, out this.eventName)) { throw new NoNullAllowedException($"event name of {evtType.FullName}"); } this.eventBaseArray = eventUnit.Meta.ConvertToBytes(); this.EventBytes = serializer.SerializeToUtf8Bytes(eventUnit.Event, evtType); this.eventTransArray = EventConverter.ConvertToBytes(new EventTransUnit(this.eventName, eventUnit.ActorId, this.eventBaseArray.AsSpan(), this.EventBytes)); this.EventUnit = eventUnit; this.Document = new EventDocument <TPrimaryKey> { ActorId = eventUnit.ActorId, Data = Encoding.UTF8.GetString(this.EventBytes), FlowId = flowId, Name = this.eventName, Version = eventUnit.Meta.Version, Timestamp = eventUnit.Meta.Timestamp }; }
protected virtual async Task <bool> RaiseEvent(IEvent @event, string flowId = null) { if (string.IsNullOrEmpty(flowId)) { flowId = RequestContext.Get(RuntimeConsts.EventFlowIdKey) as string; if (string.IsNullOrEmpty(flowId)) { throw new ArgumentNullException(nameof(flowId)); } } try { var eventBox = new EventUnit <TPrimaryKey> { Event = @event, Meta = new EventMeta { FlowId = flowId, Version = this.Snapshot.Meta.Version + 1, Timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds() }, ActorId = this.Snapshot.Meta.ActorId }; await this.OnRaiseStart(eventBox); this.Snapshot.Meta.IncrementDoingVersion(this.ActorType); // Mark the Version to be processed var evtType = @event.GetType(); if (!this.EventTypeContainer.TryGet(evtType, out var eventName)) { throw new NoNullAllowedException($"event name of {evtType.FullName}"); } var evtBytes = this.Serializer.SerializeToUtf8Bytes(@event, evtType); var appendResult = await this.EventStorage.Append(new EventDocument <TPrimaryKey> { FlowId = eventBox.Meta.FlowId, ActorId = this.ActorId, Data = Encoding.UTF8.GetString(evtBytes), Name = eventName, Timestamp = eventBox.Meta.Timestamp, Version = eventBox.Meta.Version }); if (appendResult) { this.SnapshotHandler.Apply(this.Snapshot, eventBox); this.Snapshot.Meta.UpdateVersion(eventBox.Meta, this.ActorType); // Version of the update process await this.OnRaiseSuccess(eventBox, evtBytes); await this.SaveSnapshotAsync(); using var baseBytes = eventBox.Meta.ConvertToBytes(); using var buffer = EventConverter.ConvertToBytes(new EventTransUnit(eventName, this.Snapshot.Meta.ActorId, baseBytes.AsSpan(), evtBytes)); if (this.EventStream != default) { await this.EventStream.Next(buffer.ToArray()); } if (this.Logger.IsEnabled(LogLevel.Trace)) { this.Logger.LogTrace("RaiseEvent completed: {0}->{1}->{2}", this.ActorType.FullName, this.Serializer.Serialize(eventBox), this.Serializer.Serialize(this.Snapshot)); } return(true); } else { if (this.Logger.IsEnabled(LogLevel.Trace)) { this.Logger.LogTrace("RaiseEvent failed: {0}->{1}->{2}", this.ActorType.FullName, this.Serializer.Serialize(eventBox), this.Serializer.Serialize(this.Snapshot)); } this.Snapshot.Meta.DecrementDoingVersion(); // Restore the doing version await this.OnRaiseFailed(eventBox); return(false); } } catch (Exception ex) { this.Logger.LogCritical(ex, "RaiseEvent failed: {0}->{1}", this.ActorType.FullName, this.Serializer.Serialize(this.Snapshot)); await this.RecoverySnapshot(); // Restore state // Errors may appear repeatedly, so update the previous snapshot to improve the restoration speed await this.SaveSnapshotAsync(true); throw; } }