/// <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); }
/// <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; } }