Esempio n. 1
0
        protected IEventCacheReadObject CreateOrUpdateStatusEvent(Guid accountId, BulbCacheWriteObject data)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            var request = new AccountCacheRequest()
            {
                AccountId = accountId,
                ObjectId  = data.StatusEventId
            };

            // обновляем существующее
            if (AllCaches.Events.ExistsInStorage(request))
            {
                using (var statusEvent = AllCaches.Events.Write(request))
                {
                    statusEvent.Message    = data.Message;
                    statusEvent.EndDate    = data.EndDate;
                    statusEvent.StartDate  = data.StartDate;
                    statusEvent.ActualDate = data.ActualDate;
                    statusEvent.Count      = data.Count;
                    statusEvent.BeginSave();

                    return(statusEvent);
                }
            }

            // создаем новое событие
            var ownerId = data.GetOwnerId();

            return(AddStatusEvent(accountId, data, ownerId));
        }
Esempio n. 2
0
        protected void ProlongStatus(BulbSignal signal, BulbCacheWriteObject data)
        {
            // проверим пробел
            var  nextStartDate = GetStartDate(data, signal);
            bool hasSpace      = data.ActualDate < nextStartDate;

            if (hasSpace)
            {
                throw new Exception("Тут не должно быть пробела");
            }

            // разрыва нет
            // у виртуальных колбасок нет смысла увеличивать счетчик, т.к. это приводит только к лишнему сохранению объектов
            if (data.IsLeaf)
            {
                data.Count++;
            }

            data.HasSignal = signal.HasSignal;
            data.Message   = signal.Message;
            if (signal.EventId != Guid.Empty)
            {
                data.LastEventId = signal.EventId;
            }
            data.LastChildBulbId = signal.ChildBulbId;

            // у листьев время завершения меняется,
            // а у родителей время завершения меняется только когда начинется новый статус
            if (data.IsLeaf)
            {
                // это нужно, например, чтобы у проверок и метрик EndDate показывал время последнего выполнения
                data.EndDate = signal.ProcessDate;

                // актуальность проверки и метрики определяется последним значением
                if (data.EventCategory == EventCategory.MetricStatus ||
                    data.EventCategory == EventCategory.UnitTestStatus)
                {
                    data.ActualDate = signal.ActualDate;
                }
                else if (data.EventCategory == EventCategory.ComponentEventsStatus)
                {
                    if (signal.ActualDate > data.ActualDate)
                    {
                        data.ActualDate = signal.ActualDate;
                    }
                }
                else
                {
                    throw new Exception("Неизвестный тип лампочки " + data.EventCategory);
                }
            }
            else
            {
                // у виртуальных лампочек время актуальности и завершения не меняется при продлении
                data.ActualDate = EventHelper.InfiniteActualDate;
            }

            CreateOrUpdateStatusEvent(signal.AccountId, data);
        }
Esempio n. 3
0
        protected void ChangeStatus(BulbSignal signal, BulbCacheWriteObject data)
        {
            // проверим пробел
            var startDate = GetStartDate(data, signal);

            if (startDate > data.ActualDate)
            {
                throw new Exception("startDate > data.ActualDate");
            }

            // обновим статус
            data.PreviousStatus = data.Status; // запомним предыдущий
            if (signal.EventId != Guid.Empty)
            {
                data.FirstEventId = signal.EventId;
                data.LastEventId  = signal.EventId;
            }
            data.Count           = 1;
            data.Message         = signal.Message;
            data.Status          = signal.Status;
            data.LastChildBulbId = signal.ChildBulbId;

            if (data.IsLeaf)
            {
                data.ActualDate = signal.ActualDate;
            }
            else
            {
                // время актуальности колбасок, которые НЕ являются листьями дерева, бесконечо
                data.ActualDate = EventHelper.InfiniteActualDate;
            }

            data.StartDate = startDate;
            data.HasSignal = signal.HasSignal;
            data.EndDate   = startDate; // меняется только при создании нового статуса

            var ownerId     = data.GetOwnerId();
            var statusEvent = AddStatusEvent(signal.AccountId, data, ownerId);
        }
Esempio n. 4
0
        protected IEventCacheReadObject AddStatusEvent(Guid accountId, BulbCacheWriteObject data, Guid ownerId)
        {
            var accountDbContext = Context.GetAccountDbContext(accountId);
            var eventType        = SystemEventType.GetStatusEventType(data.EventCategory);
            var now = DateTime.Now;

            // создаем новый статус
            var newStatus = new Event()
            {
                Id                 = Guid.NewGuid(),
                Message            = data.Message,
                ActualDate         = data.ActualDate,
                Category           = data.EventCategory,
                Count              = data.Count,
                CreateDate         = now,
                LastUpdateDate     = now,
                EndDate            = data.EndDate,
                Importance         = EventImportanceHelper.Get(data.Status),
                OwnerId            = ownerId,
                StartDate          = data.StartDate,
                EventTypeId        = eventType.Id,
                PreviousImportance = EventImportanceHelper.Get(data.PreviousStatus),
                IsSpace            = data.IsSpace
            };

            if (data.FirstEventId.HasValue && data.FirstEventId != Guid.Empty)
            {
                newStatus.FirstReasonEventId = data.FirstEventId;
            }
            var eventRepository = accountDbContext.GetEventRepository();

            eventRepository.Add(newStatus);

            // обновим старый статус
            var oldStatus = eventRepository.GetByIdOrNull(data.StatusEventId);

            if (oldStatus != null)
            {
                // установим флажок, если это архивный статус
                if (oldStatus.Category == EventCategory.ComponentExternalStatus)
                {
                    var archivedStatus = new ArchivedStatus()
                    {
                        EventId = oldStatus.Id
                    };
                    var archivedStatusRepository = accountDbContext.GetArchivedStatusRepository();
                    archivedStatusRepository.Add(archivedStatus);
                }

                // старый статус завершается, когда начинается новый статус
                oldStatus.ActualDate     = newStatus.StartDate;
                oldStatus.EndDate        = newStatus.StartDate;
                oldStatus.LastUpdateDate = now;

                // убедимся, что очереди изменений нет изменений старого статуста,
                // иначе наши изменения через EF могут быть перезатёрты
                using (var oldStatusCache = AllCaches.Events.GetForWrite(oldStatus, accountId))
                {
                    oldStatusCache.WaitSaveChanges();
                    oldStatusCache.Unload();
                }
            }

            // обновим лампочку через EF, чтобы {лампочка, старый статус и новый статус} сохранились одновременно
            // изменения лампочки будут сохранены дважды, воторой раз в очереди изменений
            // сейчас не понятно как этого избежать, дело в том, что после данного метода код может изменить кэш лампочки
            // и чтобы не потерять эти изменения сохраняем дважды
            data.StatusEventId = newStatus.Id;
            var bulbEF = accountDbContext.GetStatusDataRepository().GetById(data.Id);

            bulbEF.Count           = data.Count;
            bulbEF.ActualDate      = data.ActualDate;
            bulbEF.EndDate         = data.EndDate;
            bulbEF.FirstEventId    = data.FirstEventId;
            bulbEF.HasSignal       = data.HasSignal;
            bulbEF.LastEventId     = data.LastEventId;
            bulbEF.Message         = data.Message;
            bulbEF.PreviousStatus  = data.PreviousStatus;
            bulbEF.StartDate       = data.StartDate;
            bulbEF.Status          = data.Status;
            bulbEF.StatusEventId   = data.StatusEventId;
            bulbEF.LastChildBulbId = data.LastChildBulbId;

            // убедимся что в очереди изменений нет других изменений лампочки,
            // иначе сохранённые через EF изменения могут быть потеряны
            data.WaitSaveChanges();

            // todo нужно сохранять изменения в одном контексте (транзакции),
            // чтобы лампочка не потеряла ссылку на последний статус
            accountDbContext.SaveChanges();

            var rEvent = AllCaches.Events.Find(new AccountCacheRequest()
            {
                AccountId = accountId,
                ObjectId  = newStatus.Id
            });

            return(rEvent);
        }