Beispiel #1
0
        protected override async ValueTask OnTxRollback(string txId)
        {
            if (!string.IsNullOrEmpty(txId) && this.EventTypeContainer.TryGet(typeof(TxFinishedEvent), out var eventName))
            {
                var rollbackEvent = new EventUnit <TPrimaryKey>
                {
                    Event = new TxRollbackEvent {
                        Id = this.TxSnapshot.TxId
                    },
                    Meta = new EventMeta {
                        Version = this.CurrentTxEventVersion + 1, Timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds(), FlowId = txId
                    },
                    ActorId = this.ActorId
                };
                await this.TxEventStorage.Append(new EventDocument <TPrimaryKey>
                {
                    FlowId    = txId,
                    ActorId   = this.ActorId,
                    Data      = this.Serializer.Serialize(rollbackEvent.Event as TxFinishedEvent),
                    Name      = eventName,
                    Timestamp = rollbackEvent.Meta.Timestamp,
                    Version   = rollbackEvent.Meta.Version
                });

                this.TxEventApply(rollbackEvent);
                await this.ClearTxEvents();
            }
        }
Beispiel #2
0
        private void TxEventApply(EventUnit <TPrimaryKey> evt)
        {
            switch (evt.Event)
            {
            case TxCommitEvent value:
            {
                this.TxSnapshot.TxId           = value.Id;
                this.TxSnapshot.TxStartVersion = value.StartVersion;
                this.TxSnapshot.TxStartTime    = evt.Meta.Timestamp;
                this.TxSnapshot.Status         = TransactionStatus.WaitingCommit;
            }; break;

            case TxCommitedEvent _:
            {
                this.TxSnapshot.Status = TransactionStatus.Commited;
            }; break;

            case TxFinishedEvent _:
            {
                this.TxSnapshot.Reset();
            }; break;

            case TxRollbackEvent _:
            {
                this.TxSnapshot.Reset();
            }; break;

            default: throw new NotSupportedException(evt.Event.GetType().FullName);
            }
            this.CurrentTxEventVersion = evt.Meta.Version;
        }
Beispiel #3
0
        protected override async ValueTask OnTxCommited(string txId)
        {
            // If it is a transaction with Id, join the transaction event and wait for Complete
            if (!string.IsNullOrEmpty(txId) && this.EventTypeContainer.TryGet(typeof(TxCommitedEvent), out var eventName))
            {
                var commitEvent = new EventUnit <TPrimaryKey>
                {
                    Event = new TxCommitedEvent {
                        Id = this.TxSnapshot.TxId
                    },
                    Meta = new EventMeta {
                        Version = this.CurrentTxEventVersion + 1, Timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds(), FlowId = txId
                    },
                    ActorId = this.ActorId
                };
                await this.TxEventStorage.Append(new EventDocument <TPrimaryKey>
                {
                    FlowId    = txId,
                    ActorId   = this.ActorId,
                    Data      = this.Serializer.Serialize(commitEvent.Event as TxCommitedEvent),
                    Name      = eventName,
                    Timestamp = commitEvent.Meta.Timestamp,
                    Version   = commitEvent.Meta.Version
                });

                this.TxEventApply(commitEvent);
                await this.ClearTxEvents();
            }
        }
Beispiel #4
0
 private async ValueTask EventDelivered(EventUnit <TPrimaryKey> eventUnit)
 {
     try
     {
         RequestContext.Set(RuntimeConsts.EventFlowIdKey, eventUnit.Meta.FlowId);
         this.SnapshotHandler.Apply(this.Snapshot, eventUnit);
         await this.OnEventDelivered(eventUnit);
     }
     catch (Exception ex)
     {
         this.Logger.LogCritical(ex, "Delivered failed: {0}->{1}->{2}", this.ActorType.FullName, this.ActorId.ToString(), this.Serializer.Serialize(eventUnit, eventUnit.Event.GetType()));
     }
 }
Beispiel #5
0
 public void SetEventUnit(EventUnit value, Context context)
 {
     if (value == null)
     {
         eventUnit = null;
         Enabled   = false;
     }
     else if (value != eventUnit)
     {
         eventUnit = value;
         UpdateView(context);
         Enabled = true;
     }
 }
Beispiel #6
0
        protected virtual async ValueTask OnRaiseStart(EventUnit <TPrimaryKey> @event)
        {
            if (this.Snapshot.Meta.Version == 0)
            {
                return;
            }

            if (this.Snapshot.Meta.IsLatest)
            {
                await this.SnapshotStorage.UpdateIsLatest(this.Snapshot.Meta.ActorId, false);

                this.Snapshot.Meta.IsLatest = false;
            }
        }
Beispiel #7
0
        private void unitSelectorListBox_DrawItem(object sender, DrawItemEventArgs e)
        {
            // Find if units have overlapping positions
            _isPositionOccupied = new bool[evt.Units.Length];
            for (int index = 0; index < evt.Units.Length; index++)
            {
                _isPositionOccupied[index] = false;
            }

            for (int index = 0; index < evt.Units.Length; index++)
            {
                EventUnit eventUnit = evt.Units[index];
                for (int innerIndex = index + 1; innerIndex < evt.Units.Length; innerIndex++)
                {
                    EventUnit innerEventUnit = evt.Units[innerIndex];
                    if ((eventUnit.X == innerEventUnit.X) && (eventUnit.Y == innerEventUnit.Y) && (eventUnit.UpperLevel == innerEventUnit.UpperLevel) && (!eventUnit.RandomlyPresent) && (!innerEventUnit.RandomlyPresent) && (eventUnit.SpriteSet.Value > 0) && (innerEventUnit.SpriteSet.Value > 0))
                    {
                        _isPositionOccupied[index]      = true;
                        _isPositionOccupied[innerIndex] = true;
                    }
                }
            }

            bool canCheckOccupied = (_isPositionOccupied != null);

            if (canCheckOccupied)
            {
                canCheckOccupied = (_isPositionOccupied.Length == unitSelectorListBox.Items.Count);
            }

            if ((e.Index > -1) && (e.Index < unitSelectorListBox.Items.Count))
            {
                bool useOccupiedColor = canCheckOccupied ? _isPositionOccupied[e.Index] : false;

                EventUnit unit = unitSelectorListBox.Items[e.Index] as EventUnit;
                using (Brush textBrush = new SolidBrush(useOccupiedColor ? Color.Red : e.ForeColor))
                    using (Brush backBrush = new SolidBrush(e.BackColor))
                    {
                        e.Graphics.FillRectangle(backBrush, e.Bounds);
                        e.Graphics.DrawString((unit.HasChanged ? "*" : "") + unit.SpriteSet.Name, e.Font, textBrush, e.Bounds.X + 0, e.Bounds.Y + 0);
                        e.Graphics.DrawString(unit.SpecialName.Name, e.Font, textBrush, e.Bounds.X + columnWidths[0], e.Bounds.Y + 0);
                        e.Graphics.DrawString(unit.Job.Name, e.Font, textBrush, e.Bounds.X + columnWidths[0] + columnWidths[1], e.Bounds.Y + 0);
                        if ((e.State & DrawItemState.Focus) == DrawItemState.Focus)
                        {
                            e.DrawFocusRectangle();
                        }
                    }
            }
        }
Beispiel #8
0
        protected async ValueTask Tell(EventUnit <TPrimaryKey> eventUnit)
        {
            if (eventUnit.Meta.Version == this.Snapshot.Meta.Version + 1)
            {
                await this.EventDelivered(eventUnit);

                this.Snapshot.Meta.ForceUpdateVersion(eventUnit.Meta, this.ActorType); // 更新处理完成的Version
            }
            else if (eventUnit.Meta.Version > this.Snapshot.Meta.Version)
            {
                var documentList = await this.Vertex.GetEventDocuments(this.Snapshot.Meta.Version + 1, eventUnit.Meta.Version - 1);

                var evtList = documentList.Select(document =>
                {
                    if (!this.EventTypeContainer.TryGet(document.Name, out var type))
                    {
                        throw new NoNullAllowedException($"event name of {document.Name}");
                    }
                    var data = this.Serializer.Deserialize(document.Data, type);
                    return(new EventUnit <TPrimaryKey>
                    {
                        ActorId = this.ActorId,
                        Event = data as IEvent,
                        Meta = new EventMeta {
                            Version = document.Version, Timestamp = document.Timestamp, FlowId = document.FlowId
                        }
                    });
                });
                foreach (var evt in evtList)
                {
                    await this.EventDelivered(evt);

                    this.Snapshot.Meta.ForceUpdateVersion(evt.Meta, this.ActorType); // 更新处理完成的Version
                }
            }

            if (eventUnit.Meta.Version == this.Snapshot.Meta.Version + 1)
            {
                await this.EventDelivered(eventUnit);

                this.Snapshot.Meta.ForceUpdateVersion(eventUnit.Meta, this.ActorType); // 更新处理完成的Version
            }

            if (eventUnit.Meta.Version > this.Snapshot.Meta.Version)
            {
                throw new EventVersionException(this.ActorId.ToString(), this.ActorType, eventUnit.Meta.Version, this.Snapshot.Meta.Version);
            }
        }
Beispiel #9
0
        protected virtual async Task RecoverySnapshot()
        {
            try
            {
                await this.ReadSnapshotAsync();

                while (!this.Snapshot.Meta.IsLatest)
                {
                    var documentList = await this.Vertex.GetEventDocuments(this.Snapshot.Meta.Version + 1, this.Snapshot.Meta.Version + this.VertexOptions.EventPageSize);

                    foreach (var document in documentList)
                    {
                        if (!this.EventTypeContainer.TryGet(document.Name, out var type))
                        {
                            throw new NoNullAllowedException($"event name of {document.Name}");
                        }
                        var data = this.Serializer.Deserialize(document.Data, type);
                        var evt  = new EventUnit <TPrimaryKey>
                        {
                            ActorId = this.ActorId,
                            Event   = data as IEvent,
                            Meta    = new EventMeta {
                                Version = document.Version, Timestamp = document.Timestamp, FlowId = document.FlowId
                            }
                        };
                        this.Snapshot.Meta.IncrementDoingVersion(this.ActorType);   // Mark the Version to be processed
                        this.SnapshotHandler.Apply(this.Snapshot, evt);
                        this.Snapshot.Meta.UpdateVersion(evt.Meta, this.ActorType); // Version of the update process
                    }

                    if (documentList.Count < this.VertexOptions.EventPageSize)
                    {
                        break;
                    }
                }

                if (this.Logger.IsEnabled(LogLevel.Trace))
                {
                    this.Logger.LogTrace("Recovery completed: {0}->{1}", this.ActorType.FullName, this.Serializer.Serialize(this.Snapshot));
                }
            }
            catch (Exception ex)
            {
                this.Logger.LogCritical(ex, "Recovery failed: {0}->{1}", this.ActorType.FullName, this.ActorId.ToString());
                throw;
            }
        }
Beispiel #10
0
 private void unitSelectorListBox_DrawItem(object sender, DrawItemEventArgs e)
 {
     if ((e.Index > -1) && (e.Index < unitSelectorListBox.Items.Count))
     {
         EventUnit unit = unitSelectorListBox.Items[e.Index] as EventUnit;
         using (Brush textBrush = new SolidBrush(e.ForeColor))
             using (Brush backBrush = new SolidBrush(e.BackColor))
             {
                 e.Graphics.FillRectangle(backBrush, e.Bounds);
                 e.Graphics.DrawString((unit.HasChanged ? "*" : "") + unit.SpriteSet.Name, e.Font, textBrush, e.Bounds.X + 0, e.Bounds.Y + 0);
                 e.Graphics.DrawString(unit.SpecialName.Name, e.Font, textBrush, e.Bounds.X + columnWidths[0], e.Bounds.Y + 0);
                 e.Graphics.DrawString(unit.Job.Name, e.Font, textBrush, e.Bounds.X + columnWidths[0] + columnWidths[1], e.Bounds.Y + 0);
                 if ((e.State & DrawItemState.Focus) == DrawItemState.Focus)
                 {
                     e.DrawFocusRectangle();
                 }
             }
     }
 }
Beispiel #11
0
        protected override async ValueTask OnEventDelivered(EventUnit <TPrimaryKey> eventUnit)
        {
            switch (eventUnit.Event)
            {
            case CreatingEvent <TSnapshot> evt:
                await this.CreatingSnapshotHandle(evt);

                break;

            case UpdatingEvent <TSnapshot> evt:
                await this.UpdatingSnapshotHandle(evt);

                break;

            case DeletingEvent <TSnapshot> evt:
                await this.DeletingSnapshotHandle(evt);

                break;
            }
            await base.OnEventDelivered(eventUnit);
        }
Beispiel #12
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
            };
        }
Beispiel #13
0
 public static string GetEventId <TPrimaryKey>(this EventUnit <TPrimaryKey> @event)
 {
     return($"{@event.ActorId}_{@event.Meta.Version}");
 }
Beispiel #14
0
        public override void Apply(SnapshotUnit <TPrimaryKey, TSnapshot> snapshotBox, EventUnit <TPrimaryKey> eventBox)
        {
            switch (eventBox.Event)
            {
            case CreatingEvent <TSnapshot> :
                CreatingSnapshotHandle(snapshotBox.Data, (CreatingEvent <TSnapshot>)eventBox.Event);
                return;

            case UpdatingEvent <TSnapshot> :
                UpdatingSnapshotHandle(snapshotBox.Data, (UpdatingEvent <TSnapshot>)eventBox.Event);
                return;

            case DeletingEvent <TSnapshot> :
                DeletingSnapshotHandle(snapshotBox.Data, (DeletingEvent <TSnapshot>)eventBox.Event);
                return;

            default:
                base.Apply(snapshotBox, eventBox);
                return;
            }
        }
Beispiel #15
0
 protected virtual ValueTask OnRaiseFailed(EventUnit <TPrimaryKey> @event) => ValueTask.CompletedTask;
Beispiel #16
0
 protected virtual ValueTask OnRaiseSuccess(EventUnit <TPrimaryKey> eventUnit, byte[] eventBits) => this.Archive();
Beispiel #17
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;
            }
        }
Beispiel #18
0
 public ValueTask Tell_Test(EventUnit <long> eventUnit)
 {
     return(this.Tell(eventUnit));
 }
Beispiel #19
0
        private void unitSelectorListBox_DrawItem(object sender, DrawItemEventArgs e)
        {
            // Find if units have overlapping positions
            _isPositionOccupied = new bool[evt.Units.Length];
            for (int index = 0; index < evt.Units.Length; index++)
            {
                _isPositionOccupied[index] = false;
            }

            for (int index = 0; index < evt.Units.Length; index++)
            {
                EventUnit eventUnit = evt.Units[index];
                for (int innerIndex = index + 1; innerIndex < evt.Units.Length; innerIndex++)
                {
                    EventUnit innerEventUnit = evt.Units[innerIndex];
                    if ((eventUnit.X == innerEventUnit.X) && (eventUnit.Y == innerEventUnit.Y) && (eventUnit.UpperLevel == innerEventUnit.UpperLevel) &&
                        ((eventUnit.AlwaysPresent) && (innerEventUnit.AlwaysPresent)) &&
                        (eventUnit.SpriteSet.Value > 0) && (innerEventUnit.SpriteSet.Value > 0))
                    {
                        _isPositionOccupied[index]      = true;
                        _isPositionOccupied[innerIndex] = true;
                    }
                }
            }

            bool canCheckOccupied = (_isPositionOccupied != null);

            if (canCheckOccupied)
            {
                canCheckOccupied = (_isPositionOccupied.Length == unitSelectorListBox.Items.Count);
            }

            if ((e.Index > -1) && (e.Index < unitSelectorListBox.Items.Count))
            {
                bool isSelected = ((e.State & DrawItemState.Selected) == DrawItemState.Selected);
                bool isOccupied = canCheckOccupied ? _isPositionOccupied[e.Index] : false;

                EventUnit unit       = unitSelectorListBox.Items[e.Index] as EventUnit;
                bool      unitExists = (unit.SpriteSet.Value > 0);

                int colorIndex = (isSelected ? 0 : (unit.AlwaysPresent ? 1 : 2));
                int teamIndex  = (int)unit.TeamColor;
                FFTPatcher.Settings.CombinedColor teamColor = Settings.GetTeamColor(teamIndex, colorIndex);
                bool useConflictColor = (isOccupied && (!isSelected));
                bool useTeamColor     = (unitExists && teamColor.UseColor);

                Color  foreColor       = (useConflictColor ? Color.Red : (useTeamColor ? teamColor.ForegroundColor : e.ForeColor));
                Color  backColor       = (useConflictColor ? Color.White : (useTeamColor ? teamColor.BackgroundColor : e.BackColor));
                string strPresentFlags = unit.AlwaysPresent ? (unit.RandomlyPresent ? "Always/Random" : "Always") : (unit.RandomlyPresent ? "Random" : "");

                using (Brush backBrush = new SolidBrush(backColor))
                {
                    e.Graphics.FillRectangle(backBrush, e.Bounds);

                    TextRenderer.DrawText(e.Graphics, (unit.HasChanged ? "*" : "") + unit.SpriteSet.Name, e.Font, new Point(e.Bounds.X + 0, e.Bounds.Y + 0), foreColor, TextFormatFlags.NoPrefix);
                    if (unitExists)
                    {
                        TextRenderer.DrawText(e.Graphics, unit.SpecialName.Name, e.Font, new Point(e.Bounds.X + cumulativeWidths[0], e.Bounds.Y + 0), foreColor, TextFormatFlags.NoPrefix);
                        TextRenderer.DrawText(e.Graphics, unit.Job.Name, e.Font, new Point(e.Bounds.X + cumulativeWidths[1], e.Bounds.Y + 0), foreColor, TextFormatFlags.NoPrefix);
                        TextRenderer.DrawText(e.Graphics, String.Format("({0}, {1}, {2})", unit.X, unit.Y, (unit.UpperLevel ? 1 : 0)), e.Font, new Point(e.Bounds.X + cumulativeWidths[2], e.Bounds.Y), foreColor);
                        TextRenderer.DrawText(e.Graphics, String.Format("0x{0:X2}", unit.UnitID), e.Font, new Point(e.Bounds.X + cumulativeWidths[3], e.Bounds.Y + 0), foreColor);
                        TextRenderer.DrawText(e.Graphics, strPresentFlags, e.Font, new Point(e.Bounds.X + cumulativeWidths[4], e.Bounds.Y + 0), foreColor);
                        TextRenderer.DrawText(e.Graphics, unit.TeamColor.ToString(), e.Font, new Point(e.Bounds.X + cumulativeWidths[5], e.Bounds.Y + 0), foreColor);
                    }
                    if ((e.State & DrawItemState.Focus) == DrawItemState.Focus)
                    {
                        e.DrawFocusRectangle();
                    }
                }
            }
        }
Beispiel #20
0
 public EventBufferUnit(EventUnit <TPrimaryKey> eventUnit, IEventTypeContainer eventTypeContainer, ISerializer serializer)
     : this(eventUnit, default, eventTypeContainer, serializer)
 {
 }
Beispiel #21
0
 protected virtual ValueTask OnEventDelivered(EventUnit <TPrimaryKey> eventUnit) => ValueTask.CompletedTask;