Beispiel #1
0
        void IMessagingServiceInternal.PrepareIncomingReceive(TimeSpan executeInterval)
        {
            if (AppCore.GetState() != CoreComponentState.Started)
            {
                return;
            }

            var type = GetType();

            if (!_executingFlags.TryLock(TasksIncomingReceive))
            {
                return;
            }

            int messagesReceived = 0;

            try
            {
                using (var db = new DB.DataContext())
                {
                    var components = GetComponents().
                                     OfType <IncomingMessageReceiver <TMessage> >().
                                     Select(x => new
                    {
                        Component       = x,
                        IdTypeComponent = ItemTypeFactory.GetItemType(x.GetType())?.IdItemType
                    }).
                                     OrderBy(x => ((IPoolObjectOrdered)x.Component).OrderInPool).
                                     ToList();

                    var timeEnd = DateTimeOffset.Now.Add(executeInterval);

                    using (var scope = db.CreateScope(TransactionScopeOption.Suppress)) // Здесь Suppress вместо RequiresNew, т.к. весь процесс отправки занимает много времени и блокировать таблицу нельзя.
                    {
                        foreach (var componentInfo in components)
                        {
                            try
                            {
                                var messages = componentInfo.Component.OnReceive(this);
                                if (messages != null && messages.Count > 0)
                                {
                                    int countAdded = 0;
                                    foreach (var message in messages)
                                    {
                                        if (message == null)
                                        {
                                            continue;
                                        }

                                        var stateType = DB.MessageStateType.NotProcessed;
                                        if (message.IsComplete)
                                        {
                                            stateType = DB.MessageStateType.Complete;
                                        }
                                        if (message.IsError)
                                        {
                                            stateType = DB.MessageStateType.Error;
                                        }

                                        var mess = new DB.MessageQueue()
                                        {
                                            IdMessageType = IdMessageType,
                                            Direction     = true,
                                            State         = message.State,
                                            StateType     = stateType,
                                            DateCreate    = DateTime.Now,
                                            DateDelayed   = message.DateDelayed,
                                            MessageInfo   = Newtonsoft.Json.JsonConvert.SerializeObject(message.Message),
                                        };

                                        db.MessageQueue.Add(mess);
                                        countAdded++;
                                        messagesReceived++;

                                        if (countAdded >= 50)
                                        {
                                            db.SaveChanges();
                                            countAdded = 0;
                                        }
                                    }

                                    db.SaveChanges();
                                }
                            }
                            catch (Exception ex)
                            {
                                this.RegisterServiceEvent(Journaling.EventType.Error, $"Ошибка вызова '{nameof(componentInfo.Component.OnReceive)}'", $"Ошибка вызова '{nameof(componentInfo.Component.OnReceive)}' для компонента '{componentInfo?.Component?.GetType()?.FullName}'.", ex);
                                continue;
                            }

                            try
                            {
                                while (true)
                                {
                                    var message = componentInfo.Component.OnBeginReceive(this);
                                    if (message == null)
                                    {
                                        break;
                                    }

                                    DB.MessageQueue queueMessage = null;

                                    var queueState = DB.MessageStateType.NotProcessed;
                                    if (message.IsComplete)
                                    {
                                        queueState = DB.MessageStateType.Complete;
                                    }
                                    if (message.IsError)
                                    {
                                        queueState = DB.MessageStateType.Error;
                                    }

                                    try
                                    {
                                        var mess = new DB.MessageQueue()
                                        {
                                            IdMessageType = IdMessageType,
                                            Direction     = true,
                                            State         = message.State,
                                            StateType     = DB.MessageStateType.IntermediateAdded,
                                            DateCreate    = DateTime.Now,
                                            DateDelayed   = message.DateDelayed,
                                            MessageInfo   = Newtonsoft.Json.JsonConvert.SerializeObject(message.Message),
                                        };

                                        db.MessageQueue.Add(mess);
                                        db.SaveChanges();

                                        queueMessage = mess;
                                    }
                                    catch (Exception ex)
                                    {
                                        this.RegisterServiceEvent(Journaling.EventType.Error, $"Ошибка регистрации сообщения после '{nameof(componentInfo.Component.OnBeginReceive)}'", $"Ошибка регистрации сообщения после вызова '{nameof(componentInfo.Component.OnBeginReceive)}' для компонента '{componentInfo?.Component?.GetType()?.FullName}'.", ex);
                                        try
                                        {
                                            componentInfo.Component.OnEndReceive(false, message, this);
                                        }
                                        catch (Exception ex2)
                                        {
                                            this.RegisterServiceEvent(Journaling.EventType.Error, $"Ошибка вызова '{nameof(componentInfo.Component.OnBeginReceive)}'", $"Ошибка вызова '{nameof(componentInfo.Component.OnBeginReceive)}' для компонента '{componentInfo?.Component?.GetType()?.FullName}' после ошибки регистрации сообщения.", ex2);
                                        }
                                        continue;
                                    }

                                    try
                                    {
                                        var endReceiveResult = componentInfo.Component.OnEndReceive(true, message, this);
                                        if (endReceiveResult)
                                        {
                                            queueMessage.StateType = queueState;
                                        }
                                        else
                                        {
                                            db.MessageQueue.Remove(queueMessage);
                                        }
                                        db.SaveChanges();
                                    }
                                    catch (Exception ex)
                                    {
                                        this.RegisterServiceEvent(Journaling.EventType.Error, $"Ошибка вызова '{nameof(componentInfo.Component.OnBeginReceive)}'", $"Ошибка вызова '{nameof(componentInfo.Component.OnBeginReceive)}' для компонента '{componentInfo?.Component?.GetType()?.FullName}' после успешной регистрации сообщения.", ex);
                                    }

                                    if (DateTimeOffset.Now >= timeEnd)
                                    {
                                        break;
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                                this.RegisterServiceEvent(Journaling.EventType.Error, $"Ошибка вызова '{nameof(componentInfo.Component.OnBeginReceive)}'", $"Ошибка вызова '{nameof(componentInfo.Component.OnBeginReceive)}' для компонента '{componentInfo?.Component?.GetType()?.FullName}'.", ex);
                                continue;
                            }
                        }
                        db.SaveChanges();
                        scope.Complete();
                    }
                }

                if (messagesReceived > 0)
                {
                    this.RegisterServiceState(ServiceStatus.RunningIdeal, $"Сообщений получено - {messagesReceived}.");
                }

                var service = AppCore.Get <Monitor>().GetService(ServiceID);
                if (service != null && (DateTime.Now - service.LastDateEvent).TotalHours >= 1)
                {
                    this.RegisterServiceState(ServiceStatus.RunningIdeal, $"Сообщений нет, сервис работает без ошибок.");
                }
            }
            catch (Exception ex)
            {
                this.RegisterServiceState(ServiceStatus.RunningWithErrors, $"Сообщений получено - {messagesReceived}.", ex);
            }
            finally
            {
                _executingFlags.ReleaseLock(TasksIncomingReceive);
            }
        }
Beispiel #2
0
        void IMessagingServiceInternal.PrepareIncomingHandle(TimeSpan executeInterval)
        {
            if (AppCore.GetState() != CoreComponentState.Started)
            {
                return;
            }

            var type = GetType();

            if (!_executingFlags.TryLock(TasksIncomingHandle))
            {
                return;
            }
            _executingFlags.ReleaseLock(nameof(RegisterIncomingMessage));

            int messagesAll     = 0;
            int messagesHandled = 0;
            int messagesErrors  = 0;

            try
            {
                using (var db = new DB.DataContext())
                    using (var scope = db.CreateScope(TransactionScopeOption.Suppress))
                    {
                        var timeEnd = DateTimeOffset.Now.Add(executeInterval);
                        while (DateTimeOffset.Now < timeEnd)
                        {
                            var messages = GetMessages(db, true, 100, _incomingHandleQueueInfo);
                            if (messages.IsNullOrEmpty())
                            {
                                break;
                            }

                            messagesAll += messages.Count;

                            var components = GetComponents().
                                             OfType <IncomingMessageHandler <TMessage> >().
                                             Select(x => new
                            {
                                Component       = x,
                                IdTypeComponent = ItemTypeFactory.GetItemType(x.GetType())?.IdItemType
                            }).
                                             OrderBy(x => ((IPoolObjectOrdered)x.Component).OrderInPool).
                                             ToList();

                            foreach (var intermediateMessage in messages)
                            {
                                if (DateTimeOffset.Now >= timeEnd)
                                {
                                    break;
                                }

                                var componentsForMessage = components;
                                if (intermediateMessage.MessageSource.IdTypeComponent.HasValue)
                                {
                                    components = components.Where(x => x.IdTypeComponent.HasValue && x.IdTypeComponent == intermediateMessage.MessageSource.IdTypeComponent).ToList();
                                }

                                foreach (var componentInfo in components)
                                {
                                    try
                                    {
                                        var component       = componentInfo.Component;
                                        var messageInfo     = new MessageInfo <TMessage>(intermediateMessage);
                                        var componentResult = component.OnPrepare(messageInfo, this);
                                        if (componentResult != null)
                                        {
                                            intermediateMessage.MessageSource.DateChange = DateTime.Now;
                                            switch (componentResult.StateType)
                                            {
                                            case MessageStateType.Completed:
                                                intermediateMessage.MessageSource.StateType       = DB.MessageStateType.Complete;
                                                intermediateMessage.MessageSource.State           = null;
                                                intermediateMessage.MessageSource.IdTypeComponent = null;
                                                intermediateMessage.MessageSource.DateDelayed     = null;
                                                break;

                                            case MessageStateType.Delayed:
                                                intermediateMessage.MessageSource.StateType       = DB.MessageStateType.NotProcessed;
                                                intermediateMessage.MessageSource.State           = componentResult.State;
                                                intermediateMessage.MessageSource.IdTypeComponent = null;
                                                intermediateMessage.MessageSource.DateDelayed     = componentResult.DateDelayed;
                                                break;

                                            case MessageStateType.Repeat:
                                                intermediateMessage.MessageSource.StateType       = DB.MessageStateType.Repeat;
                                                intermediateMessage.MessageSource.State           = componentResult.State;
                                                intermediateMessage.MessageSource.IdTypeComponent = componentInfo.IdTypeComponent;
                                                intermediateMessage.MessageSource.DateDelayed     = componentResult.DateDelayed;
                                                break;

                                            case MessageStateType.Error:
                                                intermediateMessage.MessageSource.StateType       = DB.MessageStateType.Error;
                                                intermediateMessage.MessageSource.State           = componentResult.State;
                                                intermediateMessage.MessageSource.IdTypeComponent = null;
                                                intermediateMessage.MessageSource.DateDelayed     = null;
                                                break;
                                            }
                                            messagesHandled++;
                                            db.SaveChanges();
                                            break;
                                        }
                                    }
                                    catch
                                    {
                                        messagesErrors++;
                                        continue;
                                    }
                                }

                                _incomingHandleQueueInfo.IdQueueCurrent = intermediateMessage.MessageSource.IdQueue;
                            }
                        }
                        db.SaveChanges();
                        scope.Complete();
                    }
            }
            catch (Exception ex)
            {
                this.RegisterServiceState(ServiceStatus.RunningWithErrors, $"Сообщений получено для обработки - {messagesAll}. Обработано - {messagesHandled}. Ошибки обработки - {messagesErrors}.", ex);
            }
            finally
            {
                _executingFlags.ReleaseLock(TasksIncomingHandle);
            }
        }
Beispiel #3
0
        void IMessagingServiceInternal.PrepareOutcoming(TimeSpan executeInterval)
        {
            if (AppCore.GetState() != CoreComponentState.Started)
            {
                return;
            }

            var type = GetType();

            if (!_executingFlags.TryLock(TasksOutcomingSend))
            {
                return;
            }
            _executingFlags.ReleaseLock(nameof(RegisterOutcomingMessage));

            int messagesAll    = 0;
            int messagesSent   = 0;
            int messagesErrors = 0;

            try
            {
                using (var db = new DB.DataContext())
                    using (var scope = db.CreateScope(TransactionScopeOption.Suppress)) // Здесь Suppress вместо RequiresNew, т.к. весь процесс отправки занимает много времени и блокировать таблицу нельзя.
                    {
                        var timeEnd = DateTimeOffset.Now.Add(executeInterval);
                        while (DateTimeOffset.Now < timeEnd)
                        {
                            var messages = GetMessages(db, false, 100, _outcomingQueueInfo);
                            if (messages.IsNullOrEmpty())
                            {
                                break;
                            }
                            messagesAll += messages.Count;

                            OnBeforeExecuteOutcoming(messagesAll);

                            var processedMessages = new List <IntermediateStateMessage <TMessage> >();

                            var time = new MeasureTime();
                            foreach (var intermediateMessage in messages)
                            {
                                if (DateTimeOffset.Now >= timeEnd)
                                {
                                    break;
                                }

                                if (intermediateMessage.MessageSource.StateType == DB.MessageStateType.Error)
                                {
                                    processedMessages.Add(intermediateMessage);
                                    continue;
                                }

                                var components = GetComponents().
                                                 OfType <OutcomingMessageSender <TMessage> >().
                                                 Select(x => new
                                {
                                    Component       = x,
                                    IdTypeComponent = ItemTypeFactory.GetItemType(x.GetType())?.IdItemType
                                }).
                                                 OrderBy(x => ((IPoolObjectOrdered)x.Component).OrderInPool).
                                                 ToList();

                                if (intermediateMessage.MessageSource.IdTypeComponent.HasValue)
                                {
                                    components = components.Where(x => x.IdTypeComponent.HasValue && x.IdTypeComponent == intermediateMessage.MessageSource.IdTypeComponent).ToList();
                                }

                                foreach (var componentInfo in components)
                                {
                                    try
                                    {
                                        var component       = componentInfo.Component;
                                        var messageInfo     = new MessageInfo <TMessage>(intermediateMessage);
                                        var componentResult = component.OnSend(messageInfo, this);
                                        if (componentResult != null)
                                        {
                                            intermediateMessage.MessageSource.DateChange = DateTime.Now;
                                            switch (componentResult.StateType)
                                            {
                                            case MessageStateType.Completed:
                                                intermediateMessage.MessageSource.StateType       = DB.MessageStateType.Complete;
                                                intermediateMessage.MessageSource.State           = null;
                                                intermediateMessage.MessageSource.IdTypeComponent = null;
                                                intermediateMessage.MessageSource.DateDelayed     = null;
                                                break;

                                            case MessageStateType.Delayed:
                                                intermediateMessage.MessageSource.StateType       = DB.MessageStateType.NotProcessed;
                                                intermediateMessage.MessageSource.State           = componentResult.State;
                                                intermediateMessage.MessageSource.IdTypeComponent = null;
                                                intermediateMessage.MessageSource.DateDelayed     = componentResult.DateDelayed;
                                                break;

                                            case MessageStateType.Repeat:
                                                intermediateMessage.MessageSource.StateType       = DB.MessageStateType.Repeat;
                                                intermediateMessage.MessageSource.State           = componentResult.State;
                                                intermediateMessage.MessageSource.IdTypeComponent = componentInfo.IdTypeComponent;
                                                intermediateMessage.MessageSource.DateDelayed     = componentResult.DateDelayed;
                                                break;

                                            case MessageStateType.Error:
                                                intermediateMessage.MessageSource.StateType       = DB.MessageStateType.Error;
                                                intermediateMessage.MessageSource.State           = componentResult.State;
                                                intermediateMessage.MessageSource.IdTypeComponent = null;
                                                intermediateMessage.MessageSource.DateDelayed     = componentResult.DateDelayed;
                                                break;
                                            }
                                            messagesSent++;
                                            processedMessages.Add(intermediateMessage);
                                            break;
                                        }
                                    }
                                    catch
                                    {
                                        messagesErrors++;
                                        continue;
                                    }
                                }

                                _outcomingQueueInfo.IdQueueCurrent = intermediateMessage.MessageSource.IdQueue;

                                if (time.Calculate(false).TotalSeconds >= 3)
                                {
                                    db.SaveChanges();
                                    processedMessages.Clear();
                                    time.Start();
                                }
                            }

                            if (processedMessages.Count > 0)
                            {
                                db.SaveChanges();
                            }
                        }

                        db.SaveChanges();
                        scope.Complete();
                    }
            }
            catch (Exception ex)
            {
                this.RegisterServiceState(ServiceStatus.RunningWithErrors, $"Сообщений получено для отправки - {messagesAll}. Отправлено - {messagesSent}. Ошибки отправки - {messagesErrors}.", ex);
            }
            finally
            {
                _executingFlags.ReleaseLock(TasksOutcomingSend);
            }
        }