示例#1
0
 public void Initialize(Tick senderTick, Tick ackTick, SequenceId ackEventId, IEnumerable <Event> events)
 {
     SenderTick = senderTick;
     AckTick    = ackTick;
     AckEventId = ackEventId;
     PendingEvents.AddRange(events);
     EventsWritten = 0;
 }
示例#2
0
        public virtual void Reset()
        {
            SenderTick = Tick.INVALID;
            AckTick    = Tick.INVALID;
            AckEventId = SequenceId.INVALID;

            PendingEvents.Clear();
            Events.Clear();
            EventsWritten = 0;
        }
        public void AddBillingAddress(Address address)
        {
            if (address is null)
            {
                throw new ArgumentNullException(nameof(address));
            }

            PendingEvents.Enqueue(new BillingAddressWasAdded(AggregatedId, new { BillingAddress = address }));

            BillingAddress = address;
        }
        public Customer Create(Document document, Name name, Address address)
        {
            AggregatedId = Guid.NewGuid().ToString();

            Document       = document;
            Name           = name;
            BillingAddress = address;
            PendingEvents.Enqueue(new CustomerWasCreated(AggregatedId, new { Document, Name, BillingAddress }));

            return(this);
        }
示例#5
0
        ///// <summary>
        ///// RunStateMachine is the heart of the engine that runs the finite state machine. It is executed in a
        ///// separate thread that is started when you <see cref="Start(FiniteState)"/> the state machine.
        ///// All events that have been queued by <see cref="RaiseEvent(FiniteStateEvent)"/>, are processed here.
        ///// The method runs in an infinite loop that only exits when <see cref="Stop()"/> is called.
        ///// When it has processed all of the events in the queue, it will sleep until it is pulsed
        ///// by either <see cref="RaiseEvent(FiniteStateEvent)"/> or <see cref="Stop()"/>
        ///// </summary>
        //public void RunStateMachine()
        //{
        //    string methodName = System.Reflection.MethodBase.GetCurrentMethod().Name;
        //    if (log.IsDebugEnabled)
        //        log.Debug($"{methodName}: enter");
        //
        //    try
        //    {
        //        while (!stopRequested)
        //        {
        //            HandlePendingEvents();
        //            if (!stopRequested)
        //            {
        //                lock (locker)
        //                {
        //                    if (log.IsDebugEnabled)
        //                        log.Debug($"{methodName}: Putting to sleep the state machine thread.");
        //
        //                    Monitor.Wait(locker); // Nothing to do, so go to sleep until we are pulsed by RaiseEvent or Stop
        //
        //                    if (log.IsDebugEnabled)
        //                        log.Debug($"{methodName}: Just woke up :-)");
        //                }
        //            }
        //        }
        //    }
        //    catch(Exception e)
        //    {
        //        log.Error($"{e.Message}");
        //        //OnExceptionAction?.Invoke(e);
        //    }
        //    finally
        //    {
        //        if (log.IsDebugEnabled)
        //            log.Debug($"{methodName}: exit");
        //    }
        //}
        //

        /// <summary>
        /// This function is called during the first call to RaiseEvent() in Start() because at that point,
        /// we are not handling a previous event. From then on, every event handler raises an event.
        /// </summary>
        public void HandlePendingEvents()
        {
            string methodName = System.Reflection.MethodBase.GetCurrentMethod().Name;

            if (log.IsDebugEnabled)
            {
                log.Debug($"{methodName}: enter");
            }

            try
            {
                while (PendingEvents.Count > 0)
                {
                    if (log.IsDebugEnabled)
                    {
                        log.Debug($"{methodName}: PendingEvents.Count={PendingEvents.Count}");
                    }
                    FiniteStateEvent ev = null;
                    lock (PendingEvents)
                    {
                        ev = PendingEvents.Dequeue();
                    }
                    if (CurrentState.Transitions.TryGetValue(ev.Name, out FiniteStateTransition transition))
                    {
                        if (log.IsDebugEnabled)
                        {
                            log.Debug($"{methodName}: transition {CurrentState.Name} -> {ev.Name} ->{transition.ToState.Name}");
                        }
                        SetCurrentState(transition.ToState);
                        if (log.IsDebugEnabled)
                        {
                            log.Debug($"{methodName}: before invoke, PendingEvents.Count={PendingEvents.Count}");
                        }
                        CurrentState.OnEnterAction?.Invoke();
                        if (log.IsDebugEnabled)
                        {
                            log.Debug($"{methodName}: after invoke, PendingEvents.Count={PendingEvents.Count}");
                        }
                    }
                    else
                    {
                        throw new ArgumentException($"Failed to find a transition for event '{ev.Name}' from state '{CurrentState.Name}'.");
                    }
                }
            }
            finally
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug($"{methodName}: exit");
                }
            }
        }
 public void UpdateShippingStatus(ShippingConfirmation shippingConfirmation)
 {
     if (shippingConfirmation.Status == ShippingStatus.Success)
     {
         Status = Status.Arranged;
         PendingEvents.Add(new ShippingArranged
         {
             OrderId = OrderId
         });
     }
     else
     {
         Status = Status.Postponed;
     }
 }
        public void ConfirmEmail(Email email)
        {
            var exist = Emails.Any(item => item.Equals(email));

            if (exist)
            {
                Emails.Remove(email);
                Emails.Add(email);
            }
            else
            {
                throw new InvalidOperationException("Email not exist");
            }

            PendingEvents.Enqueue(new EmailWasConfirmed(AggregatedId, new { Email = email }));
        }
示例#8
0
        /// <summary>
        /// Raises an event in the finite state machine.
        /// </summary>
        /// <param name="e">The instance of the event to raise</param>
        public void RaiseEvent(FiniteStateEvent e)
        {
            string methodName = System.Reflection.MethodBase.GetCurrentMethod().Name;

            if (log.IsDebugEnabled)
            {
                log.Debug($"{methodName}: enter");
            }
            try
            {
                if (log.IsInfoEnabled)
                {
                    log.Info($"{methodName}: [{e.Name}]");
                }
                //
                //  Use a queue so that event handlers can raise events.
                //
                lock (PendingEvents)
                {
                    PendingEvents.Enqueue(e);

                    if (log.IsDebugEnabled)
                    {
                        log.Debug($"{methodName}: handlingEvent = {handlingEvent}");
                    }

                    if (handlingEvent)
                    {
                        return;
                    }
                    handlingEvent = true;
                }
                HandlePendingEvents();
                // eliminate race for the flag by using the same lock object
                lock (PendingEvents)
                {
                    handlingEvent = false;
                }
            }
            finally
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug($"{methodName}: exit");
                }
            }
        }
        public void SimulateTime(double time)
        {
            double endTime = CurrentTime + time;

            while (PendingEvents.HasEvent && PendingEvents.FirstEventTime < endTime)
            {
                if (PendingEvents.FirstEventTime > CurrentTime)
                {
                    CurrentTime = PendingEvents.FirstEventTime;
                }

                var e = PendingEvents.NextEvent();

                ISimulatedDevice device = e.Origin as ISimulatedDevice;

                e.Origin.PastEvents.Append(e);

                switch (e.Type)
                {
                case EventType.NodePowerOn:
                    device.DeviceStart();
                    break;

                case EventType.NodePowerOff:
                    // Future feature - nodes can be powered off and leave the network.
                    throw new NotImplementedException();
                    break;

                case EventType.PacketComplete:
                    var pkt = e.EventContext as WirelessPacketTransmission;
                    e.Origin.InFlightPackets.Remove(pkt);
                    if (pkt.ReceiveSuccess)
                    {
                        device.ReceivePacket(pkt.Packet.PacketContents);
                    }
                    break;

                case EventType.TimerComplete:
                    e.Origin.TimerAction?.Invoke();
                    break;

                default:
                    throw new NotSupportedException("Unsupported event type in queue");
                }
            }
            CurrentTime = endTime;
        }
示例#10
0
 protected void Enqueue(Event @event)
 {
     Version++;
     PendingEvents.Enqueue(@event);
 }
示例#11
0
 protected void Dequeue()
 {
     PendingEvents.Dequeue();
 }