示例#1
0
        /// <summary>
        /// Updates message state after attempt to sent.
        /// </summary>
        /// <param name="task">Task with <see cref="SendMessage"/> method.</param>
        /// <param name="state">The message we were trying to send.</param>
        private void SendingTaskContinuation(Task <bool> task, object state)
        {
            var          message      = (Message)state;
            Subscription subscription = _subscriptionsManager.GetSubscriptions(message.Recipient.ID).First(s => s.MessageType.ID == message.MessageType.ID);

            lock (_lock)
            {
                _sendingTasksCount--;
                _clientConnections[(KeyGuid)message.Recipient.__PrimaryKey]--;
            }

            if (EnableOnlineState)
            {
                _statisticsService.NotifyDecConnectionCount(subscription, message);
            }
            else
            {
                _statisticsService.NotifyDecConnectionCount(subscription);
            }

            var existNewMessageWithGroup = false;

            if (!string.IsNullOrEmpty(message.Group))
            {
                LoadingCustomizationStruct lcs = MessageBS.GetMessagesWithGroupLCS(message.Recipient, message.MessageType, message.Group);
                lcs.LimitFunction = SQLWhereLanguageDef.LanguageDef.GetFunction(
                    SQLWhereLanguageDef.LanguageDef.funcAND,
                    SQLWhereLanguageDef.LanguageDef.GetFunction(
                        SQLWhereLanguageDef.LanguageDef.funcNEQ,
                        new VariableDef(SQLWhereLanguageDef.LanguageDef.GuidType, SQLWhereLanguageDef.StormMainObjectKey),
                        ((KeyGuid)message.__PrimaryKey).Guid),
                    lcs.LimitFunction);

                existNewMessageWithGroup = _dataService.GetObjectsCount(lcs) > 0;
            }

            if (existNewMessageWithGroup || (task.Status == TaskStatus.RanToCompletion && task.Result))
            {
                message.SetStatus(ObjectStatus.Deleted);
            }
            else
            {
                message.ErrorCount++;
                message.IsSending = false;

                if (!message.Recipient.SequentialSent)
                {
                    int timeoutInMinutes = AdditionalMinutesBetweenRetries * message.ErrorCount;
                    message.SendingTime = DateTime.Now + new TimeSpan(0, timeoutInMinutes, 0);
                }
            }

            ServiceHelper.UpdateObject(_dataService, message, _logger, _statisticsService);
        }
        /// <summary>
        /// Метод, выполняющийся после завершения задачи отправки сообщения.
        /// </summary>
        /// <param name="task">Задача, по завершению которой запущен метод.</param>
        /// <param name="messageObject">Сообщение, которое отправлялось в указанной задаче.</param>
        private void SendingTaskContinuation(Task <bool> task, object messageObject)
        {
            Interlocked.Decrement(ref _sendingTasksCount);

            var          message      = (Message)messageObject;
            Subscription subscription = _subscriptionsManager
                                        .GetSubscriptions(message.Recipient.ID)
                                        .FirstOrDefault(x => x.MessageType.ID == message.MessageType.ID);

            if (EnableOnlineState)
            {
                _statisticsService.NotifyDecConnectionCount(subscription, message);
            }
            else
            {
                _statisticsService.NotifyDecConnectionCount(subscription);
            }

            var existNewMessageWithGroup = false;

            if (!string.IsNullOrEmpty(message.Group))
            {
                LoadingCustomizationStruct lcs = MessageBS.GetMessagesWithGroupLCS(message.Recipient, message.MessageType, message.Group);
                lcs.LimitFunction = _langDef.GetFunction(
                    _langDef.funcAND,
                    _langDef.GetFunction(
                        _langDef.funcNEQ,
                        new VariableDef(_langDef.GuidType, ExternalLangDef.StormMainObjectKey),
                        ((KeyGuid)message.__PrimaryKey).Guid),
                    lcs.LimitFunction);

                existNewMessageWithGroup = _dataService.GetObjectsCount(lcs) > 0;
            }

            if (existNewMessageWithGroup || (task.Status == TaskStatus.RanToCompletion && task.Result))
            {
                message.SetStatus(ObjectStatus.Deleted);
            }
            else
            {
                message.ErrorCount++;
                message.IsSending = false;

                // Время следующей отправки прямо пропорционально числу неудачных попыток.
                int timeoutInMinutes = AdditionalMinutesBetweenRetries * message.ErrorCount;
                message.SendingTime = DateTime.Now + new TimeSpan(0, timeoutInMinutes, 0);
            }

            ServiceHelper.UpdateObject(_dataService, message, _logger, _statisticsService);
        }
示例#3
0
        /// <summary>
        /// Принять сообщение с именем группы.
        /// </summary>
        /// <param name="message">Принимаемое сообщение.</param>
        /// <param name="groupName">Имя группы.</param>
        public override void AcceptMessage(ServiceBusMessage message, string groupName)
        {
            _logger.LogIncomingMessage(message);
            try
            {
                if (!_objectRepository.GetRestrictionsForClient(message.ClientID).Any(x => x.MessageType.ID == message.MessageTypeID))
                {
                    _logger.LogInformation("Отправка запрещена.", $"Клиент {message.ClientID} не имеет прав на отправку сообщения типа {message.MessageTypeID}.");
                    return;
                }

                IEnumerable <Subscription> subscriptions = _subscriptionsManager.GetSubscriptionsForMsgType(message.MessageTypeID, message.ClientID);

                if (!subscriptions.Any())
                {
                    _logger.LogInformation("Для сообщения нет ни одной подписки.", $"Было получено сообщение, для которого нет ни одной активной подписки (ID типа сообщения: {message.MessageTypeID}).");
                    return;
                }

                string signature = $"{nameof(DefaultReceivingManager)}.{nameof(AcceptMessage)}({nameof(ServiceBusMessage)} {nameof(message)}, string {nameof(groupName)})";
                foreach (var subscription in subscriptions)
                {
                    Tuple <Guid, string> lockKey = Tuple.Create(((KeyGuid)subscription.__PrimaryKey).Guid, groupName);
                    object lockObject            = locker.GetLock(lockKey);
                    try
                    {
                        lock (lockObject)
                        {
                            LoadingCustomizationStruct lcs = MessageBS.GetMessagesWithGroupLCS(subscription.Client, subscription.MessageType, groupName);
                            lcs.ColumnsSort = new[] { new ColumnsSortDef(Information.ExtractPropertyPath <Message>(m => m.SendingTime), SortOrder.Desc) };

                            Stopwatch    stopwatch        = Stopwatch.StartNew();
                            DataObject[] existingMessages = _dataService.LoadObjects(lcs);
                            stopwatch.Stop();

                            _statisticsService.NotifyAvgTimeSql(subscription, (int)stopwatch.ElapsedMilliseconds, $"{signature} - find existing message.");

                            var messageWithGroup = new Message();
                            if (existingMessages.Length > 0)
                            {
                                messageWithGroup.SetExistObjectPrimaryKey(existingMessages[0].__PrimaryKey);

                                stopwatch = Stopwatch.StartNew();
                                _dataService.LoadObject(Message.Views.MessageEditView, messageWithGroup);
                                stopwatch.Stop();

                                _statisticsService.NotifyAvgTimeSql(subscription, (int)stopwatch.ElapsedMilliseconds, $"{signature} - load existing message.");
                            }

                            ServiceHelper.SetMessageWithGroupValues(message, subscription, messageWithGroup, groupName, _dataService, _logger, _statisticsService);
                            messageWithGroup.SendingTime = DateTime.Now;

                            stopwatch = Stopwatch.StartNew();
                            _dataService.UpdateObject(messageWithGroup);
                            stopwatch.Stop();

                            _statisticsService.NotifyAvgTimeSql(subscription, (int)stopwatch.ElapsedMilliseconds, $"{signature} - update message.");
                        }
                    }
                    finally
                    {
                        locker.FreeLock(lockKey);
                    }

                    _statisticsService.NotifyMessageReceived(subscription);
                }
            }
            catch (Exception e)
            {
                _logger.LogUnhandledException(e);
                throw;
            }
        }