Example #1
0
        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());
        }
Example #2
0
        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
            };
        }
Example #3
0
        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;
            }
        }