Example #1
0
        private List <DeviceEventContainer> OrganizeEventsByDevice(string entityType, string entityId, IEnumerable <ModelEvent> newEvents)
        {
            List <DeviceEventContainer> containerList = new List <DeviceEventContainer>();
            var deviceGroups = newEvents.GroupBy(e => e.DeviceID);

            foreach (var device in deviceGroups)
            {
                DeviceEventContainer deviceContainer = new DeviceEventContainer();
                deviceContainer.EntityType = entityType;
                deviceContainer.EntityID   = entityId;
                deviceContainer.DeviceID   = device.Key;

                deviceContainer.ConflictResolutionEvents = device.Where(e => e is ConflictResolutionEvent).Select(e => (ConflictResolutionEvent)e).ToList();

                // ignoredEvents contains the IDs of all previously ignored events as well
                HashSet <Guid> ignoredEvents = new HashSet <Guid>(deviceContainer.ConflictResolutionEvents.SelectMany(c => c.EventsToIgnore));

                var eventsWithoutResolution = device.Where(e => !(e is ConflictResolutionEvent));
                deviceContainer.DeviceEvents            = eventsWithoutResolution.Where(e => !ignoredEvents.Contains(e.EventID)).OrderBy(e => e.EventVector).ToList();
                deviceContainer.PreviouslyIgnoredEvents = eventsWithoutResolution.Where(e => ignoredEvents.Contains(e.EventID)).OrderBy(e => e.EventVector).ToList();

                deviceContainer.MaxVectorClock = deviceContainer.DeviceEvents.OrderBy(e => e.EventVector).LastOrDefault()?.EventVector;
                deviceContainer.MaxVectorClockIncludingResolutions = device.OrderBy(e => e.EventVector).Last().EventVector;
                containerList.Add(deviceContainer);
            }

            return(containerList);
        }
Example #2
0
        private List <ConflictResolutionEvent> ResolveConflict(string entityType, string entityId, List <DeviceEventContainer> deviceEvents, VectorClock internalVector)
        {
            //First get a list of exisiting conflict resolutions
            List <ConflictResolutionEvent> resolutionEvents = new List <ConflictResolutionEvent>();

            resolutionEvents.AddRange(deviceEvents.SelectMany(e => e.ConflictResolutionEvents));

            List <Guid>          eventsToIgnore       = new List <Guid>();
            DeviceEventContainer deviceWithlastAction = null; //Null means the current device has the last action
            VectorClock          mostRecentVector     = internalVector;

            foreach (var device in deviceEvents)
            {
                if (device.MaxVectorClock == null && device.DeviceEvents.Count == 0)
                {
                    continue; //All events were ignored and no new events to consider
                }
                if (mostRecentVector.CompareTo(device.MaxVectorClock) == -1)
                {
                    deviceWithlastAction = device;
                    mostRecentVector     = device.MaxVectorClock;
                }
                else
                {
                    eventsToIgnore.AddRange(device.DeviceEvents.Select(e => e.EventID));
                }
            }

            if (deviceWithlastAction != null)
            {
                //Ignore the current device events
                var vectors = EventStore.GetEntityEventVectors(entityType, entityId);
                foreach (var vector in vectors)
                {
                    if (vector.Vector.CompareVectors(deviceWithlastAction.MaxVectorClock) == VectorClock.ComparisonResult.Simultaneous)
                    {
                        eventsToIgnore.Add(vector.EventID);
                    }
                }
            }

            if (eventsToIgnore.Count > 0)
            {
                resolutionEvents.Add(new ConflictResolutionEvent(entityType, entityId, eventsToIgnore));
            }

            return(resolutionEvents);
        }