示例#1
0
 public AddEventResult(BufferEventData bufferEventData)
 {
     if (bufferEventData == null)
     {
         throw new ArgumentNullException("bufferEventData");
     }
     BufferEventData = bufferEventData;
 }
示例#2
0
        protected virtual void PrepareBufferEventData(BufferEventData bufferEvent)
        {
            // обрежим длинные свойства события
            PrepareDataHelper.PrepareEvent(bufferEvent.SendEventBase);

            // установим GlobalJoinKey
            bufferEvent.GlobalJoinKey = GetGlobalJoinKey(
                bufferEvent.ComponentControl,
                bufferEvent.SendEventBase);
        }
示例#3
0
        public AddEventResult AddEvent(SendEventBase eventBase)
        {
            var inputEvent = new BufferEventData(eventBase.ComponentControl, eventBase);

            if (eventBase.Ignore)
            {
                // если игнорируем, то в очередь НЕ помещем
                inputEvent.Status = AddEventStatus.Removed;
                return(new AddEventResult(inputEvent));
            }
            var outputEvent = AddOrJoin(inputEvent);

            return(new AddEventResult(outputEvent));
        }
示例#4
0
 public void Add(BufferEventData bufferEvent)
 {
     lock (SynchRoot)
     {
         List <BufferEventData> list = null;
         if (Events.TryGetValue(bufferEvent.GlobalJoinKey, out list) == false)
         {
             list = new List <BufferEventData>();
             Events.Add(bufferEvent.GlobalJoinKey, list);
         }
         list.Add(bufferEvent);
         bufferEvent.Size = 0;
         UpdateSize(bufferEvent);
     }
 }
示例#5
0
 protected virtual bool AreJoinPropertiesEqual(BufferEventData a, BufferEventData b)
 {
     // должны быть равны = EventCategory + JoinKey + IsServerTime + ComponentSystemName + TypeSystemName
     return(a.SendEventBase.EventCategory == b.SendEventBase.EventCategory &&
            a.SendEventBase.JoinKey == b.SendEventBase.JoinKey &&
            (a.SendEventBase.Importance ?? EventImportance.Unknown) == (b.SendEventBase.Importance ?? EventImportance.Unknown) &&
            a.SendEventBase.IsServerTime == b.SendEventBase.IsServerTime &&
            string.Equals(
                a.ComponentControl.SystemName,
                b.ComponentControl.SystemName,
                StringComparison.OrdinalIgnoreCase) &&
            string.Equals(
                a.SendEventBase.TypeSystemName,
                b.SendEventBase.TypeSystemName,
                StringComparison.OrdinalIgnoreCase));
 }
示例#6
0
 public void UpdateSize(BufferEventData bufferEvent)
 {
     lock (SynchRoot)
     {
         int oldSize = bufferEvent.Size;
         bufferEvent.Size = bufferEvent.GetSize();
         SizeBytes       -= oldSize;
         SizeBytes       += bufferEvent.Size;
         if (SizeBytes < 0)
         {
             SizeBytes = 0;
         }
         if (SizeBytes > MaxSizeBytes)
         {
             Client.InternalLog.Warning("Очищаем очередь событий");
             var allEvents = GetAll();
             allEvents = allEvents.OrderBy(x => x.LastAttempSendOrJoinDate).ToList();
             foreach (var bufferEventData in allEvents)
             {
                 // удаляем события пока размер очереди не будет меньше половины максимума
                 if (SizeBytes < MaxSizeBytes / 2)
                 {
                     break;
                 }
                 List <BufferEventData> list = null;
                 if (Events.TryGetValue(bufferEventData.GlobalJoinKey, out list))
                 {
                     if (list.Remove(bufferEventData))
                     {
                         SizeBytes -= bufferEvent.Size;
                         if (list.Count == 0)
                         {
                             Events.Remove(bufferEventData.GlobalJoinKey);
                         }
                     }
                 }
             }
             if (Count() == 0)
             {
                 SizeBytes = 0;
             }
             Client.InternalLog.Debug("Очередь событий очищена");
         }
     }
 }
示例#7
0
        protected BufferEventData AddOrJoin(BufferEventData newBufferEvent)
        {
            Queue.MaxSizeBytes = Client.Config.Events.EventManager.QueueBytes;
            PrepareBufferEventData(newBufferEvent);
            lock (Queue.SynchRoot)
            {
                // если JoinInterval==0, то склеивать нельзя
                if (newBufferEvent.SendEventBase.JoinInterval == TimeSpan.Zero)
                {
                    Queue.Add(newBufferEvent);
                    return(newBufferEvent);
                }

                // проверим, можно ли склеить
                var bufferEvents = Queue.GetAllByGlobalJoinKey(newBufferEvent.GlobalJoinKey);

                // склеивать можно только с последним, поэтому отсортируем по дате создания
                bufferEvents = bufferEvents.OrderByDescending(x => x.CreateDate).ToList();

                var lastEvent = bufferEvents.FirstOrDefault(x => AreJoinPropertiesEqual(x, newBufferEvent));

                // если это первое событие
                if (lastEvent == null)
                {
                    Queue.Add(newBufferEvent);
                    return(newBufferEvent);
                }

                // рассчитаем время склейки
                TimeSpan joinInterval  = newBufferEvent.SendEventBase.JoinInterval ?? TimeSpan.Zero;
                var      currentDate   = newBufferEvent.SendEventBase.StartDate.Value;
                bool     canJoinByTime = currentDate + joinInterval >= currentDate;

                // если событие уже было и время склейки НЕ протухло
                if (canJoinByTime)
                {
                    lock (lastEvent.SynchRoot)
                    {
                        // увеличим счетчик
                        lastEvent.SendEventBase.Count = AddCount(lastEvent.SendEventBase.Count ?? 1, newBufferEvent.SendEventBase.Count ?? 1);

                        // дату начала не меняем!

                        // обновим сообщение
                        lastEvent.SendEventBase.Message = newBufferEvent.SendEventBase.Message;

                        // обновим важность
                        lastEvent.SendEventBase.Importance = newBufferEvent.SendEventBase.Importance;

                        lastEvent.LastAddDate = newBufferEvent.CreateDate;

                        if (lastEvent.Status == AddEventStatus.Sended)
                        {
                            lastEvent.Status = AddEventStatus.WaitForJoin;
                        }
                        else if (lastEvent.Status == AddEventStatus.Joined)
                        {
                            lastEvent.Status = AddEventStatus.WaitForJoin;
                        }
                    }
                    return(lastEvent);
                }

                // если такое событие уже было, но время склейки протухло
                Queue.Add(newBufferEvent);
                return(newBufferEvent);
            }
        }
示例#8
0
        protected virtual void BeginFlush(DateTime date)
        {
            try
            {
                if (Disabled)
                {
                    return;
                }
                if (Queue.Count() == 0)
                {
                    return;
                }

                if (Client.CanSendData == false)
                {
                    return;
                }

                if (Client.CanConvertToServerDate() == false)
                {
                    return;
                }

                List <BufferEventData> allEvents = null;
                lock (Queue.SynchRoot)
                {
                    allEvents = Queue.GetAll();
                }

                if (allEvents == null || allEvents.Count == 0)
                {
                    return;
                }

                // получаем события для отправки
                int maxSendCount = Client.Config.Events.EventManager.MaxSend;

                var sendEvents = allEvents
                                 .Where(x =>
                                        x.Status == AddEventStatus.WaitForSend &&
                                        x.CreateDate <= date &&
                                        x.ComponentControl.IsFake() == false)
                                 .OrderBy(x => x.Errors)
                                 .ThenBy(x => x.CreateDate)
                                 .Take(maxSendCount)
                                 .ToList();

                // получаем события для склейки
                int maxJoinCount = Client.Config.Events.EventManager.MaxJoin;

                var joinEvents = allEvents
                                 .Where(x =>
                                        x.Status == AddEventStatus.WaitForJoin &&
                                        x.ComponentControl.IsFake() == false &&
                                        x.LastAttempSendOrJoinDate <= date)
                                 .OrderBy(x => x.Errors)
                                 .Take(maxJoinCount)
                                 .ToList();

                // создаем задачи для отправки
                foreach (var bufferEventData in sendEvents)
                {
                    BufferEventData data = bufferEventData;
                    TaskQueue.Add(() => SendOneEvent(data));
                }

                // создаем задачи для склейки
                if (joinEvents.Any(x => x.ComponentControl.Info == null))
                {
                    throw new Exception("joinEvents.Any(x => x.ComponentControl.Info == null)");
                }
                joinEvents = joinEvents.OrderBy(x => x.ComponentControl.Info.Id).ToList();
                const int batchCount  = 20;// будем продлевать 20 событий за раз
                var       batchEvents = new List <BufferEventData>(batchCount);
                foreach (var bufferEventData in joinEvents)
                {
                    batchEvents.Add(bufferEventData);
                    if (batchEvents.Count == batchCount)
                    {
                        var tempEvents1 = new List <BufferEventData>();
                        tempEvents1.AddRange(batchEvents);
                        TaskQueue.Add(() => JoinEvents(tempEvents1));
                        batchEvents.Clear();
                    }
                }
                if (batchEvents.Count > 0)
                {
                    var tempEvents = new List <BufferEventData>();
                    tempEvents.AddRange(batchEvents);
                    TaskQueue.Add(() => JoinEvents(tempEvents));
                }
            }
            catch (Exception exception)
            {
                Client.InternalLog.Error("Ошибка обработки очереди событий", exception);
            }
        }
示例#9
0
        protected void SendOneEvent(BufferEventData bufferEventData)
        {
            if (Client.CanSendData == false)
            {
                return;
            }
            if (Client.CanConvertToServerDate() == false)
            {
                return;
            }
            bool success = false;

            try
            {
                int oldCount = 0;

                SendEventBase eventBase = null;

                lock (bufferEventData.SynchRoot)
                {
                    oldCount = bufferEventData.SendEventBase.Count.Value;
                    if (bufferEventData.Status != AddEventStatus.WaitForSend)
                    {
                        success = true;
                        return;
                    }
                    eventBase = bufferEventData.SendEventBase.CreateBaseCopy();
                    bufferEventData.Status = AddEventStatus.BeginSend;
                }

                var response = eventBase.Send();

                lock (bufferEventData.SynchRoot)
                {
                    bufferEventData.LastAttempSendOrJoinDate = DateTime.Now;
                    if (response.Success)
                    {
                        bufferEventData.EventId     = response.Data.EventId;
                        bufferEventData.EventTypeId = response.Data.EventTypeId;
                        bufferEventData.Errors      = 0;
                        bufferEventData.LastSuccessSendOrJoinDate = bufferEventData.LastAttempSendOrJoinDate;

                        // вычтим из текущего Count то что отправили
                        if (bufferEventData.SendEventBase.Count < int.MaxValue)
                        {
                            bufferEventData.SendEventBase.Count -= oldCount;
                        }
                        if (bufferEventData.SendEventBase.Count < 0)
                        {
                            bufferEventData.SendEventBase.Count = 0;
                        }

                        if (bufferEventData.Status != AddEventStatus.Removed)
                        {
                            if (bufferEventData.SendEventBase.Count > 1)
                            {
                                bufferEventData.Status = AddEventStatus.WaitForJoin;
                            }
                            else
                            {
                                bufferEventData.Status = AddEventStatus.Sended;
                            }
                        }
                        success = true;
                    }
                }
            }
            catch (Exception exception)
            {
                Client.InternalLog.Error("Ошибка отправки события из очереди", exception);
            }
            finally
            {
                lock (bufferEventData.SynchRoot)
                {
                    if (success)
                    {
                    }
                    else
                    {
                        if (bufferEventData.Status != AddEventStatus.Removed)
                        {
                            bufferEventData.Status = AddEventStatus.WaitForSend;
                        }
                        bufferEventData.Errors++;
                    }
                }
            }
        }