private void TryPublishQueuedMessage(ManagedMqttApplicationMessage message) { Exception transmitException = null; try { _mqttClient.PublishAsync(message.ApplicationMessage).GetAwaiter().GetResult(); _storageManager?.RemoveAsync(message).GetAwaiter().GetResult(); } catch (MqttCommunicationException exception) { transmitException = exception; _logger.Warning(exception, $"Publishing application ({message.Id}) message failed."); if (message.ApplicationMessage.QualityOfServiceLevel > MqttQualityOfServiceLevel.AtMostOnce) { _messageQueue.Add(message); } } catch (Exception exception) { transmitException = exception; _logger.Error(exception, $"Unhandled exception while publishing application message ({message.Id})."); } finally { ApplicationMessageProcessed?.Invoke(this, new ApplicationMessageProcessedEventArgs(message, transmitException)); } }
public async Task AddAsync(ManagedMqttApplicationMessage applicationMessage) { using (await _messagesLock.LockAsync(CancellationToken.None).ConfigureAwait(false)) { _messages.Add(applicationMessage); await SaveAsync().ConfigureAwait(false); } }
public async Task AddAsync(ManagedMqttApplicationMessage applicationMessage) { if (applicationMessage == null) throw new ArgumentNullException(nameof(applicationMessage)); using (await _messagesLock.WaitAsync(CancellationToken.None).ConfigureAwait(false)) { _messages.Add(applicationMessage); await SaveAsync().ConfigureAwait(false); } }
private void TryPublishQueuedMessage(ManagedMqttApplicationMessage message) { Exception transmitException = null; try { //_mqttClient.PublishAsync(message.ApplicationMessage).GetAwaiter().GetResult(); AsyncContext.Run(() => _mqttClient.PublishAsync(message.ApplicationMessage).ConfigureAwait(false)); lock (_messageQueue) //lock to avoid conflict with this.PublishAsync { //While publishing this message, this.PublishAsync could have booted this //message off the queue to make room for another (when using a cap //with the DropOldestQueuedMessage strategy). If the first item //in the queue is equal to this message, then it's safe to remove //it from the queue. If not, that means this.PublishAsync has already //removed it, in which case we don't want to do anything. _messageQueue.RemoveFirst(i => i.Id.Equals(message.Id)); } //_storageManager?.RemoveAsync(message).GetAwaiter().GetResult(); if (_storageManager != null) { AsyncContext.Run(() => _storageManager.RemoveAsync(message).ConfigureAwait(false)); } } catch (MqttCommunicationException exception) { transmitException = exception; _logger.Warning(exception, $"Publishing application ({message.Id}) message failed."); if (message.ApplicationMessage.QualityOfServiceLevel == MqttQualityOfServiceLevel.AtMostOnce) { //If QoS 0, we don't want this message to stay on the queue. //If QoS 1 or 2, it's possible that, when using a cap, this message //has been booted off the queue by this.PublishAsync, in which case this //thread will not continue to try to publish it. While this does //contradict the expected behavior of QoS 1 and 2, that's also true //for the usage of a message queue cap, so it's still consistent //with prior behavior in that way. lock (_messageQueue) //lock to avoid conflict with this.PublishAsync { _messageQueue.RemoveFirst(i => i.Id.Equals(message.Id)); } } } catch (Exception exception) { transmitException = exception; _logger.Error(exception, $"Unhandled exception while publishing application message ({message.Id})."); } finally { ApplicationMessageProcessed?.Invoke(this, new ApplicationMessageProcessedEventArgs(message, transmitException)); } }
public async Task RemoveAsync(ManagedMqttApplicationMessage applicationMessage) { using (await _messagesLock.LockAsync(CancellationToken.None).ConfigureAwait(false)) { var index = _messages.IndexOf(applicationMessage); if (index == -1) { return; } _messages.RemoveAt(index); await SaveAsync().ConfigureAwait(false); } }
public async Task PublishAsync(ManagedMqttApplicationMessage applicationMessage) { if (applicationMessage == null) { throw new ArgumentNullException(nameof(applicationMessage)); } if (_storageManager != null) { await _storageManager.AddAsync(applicationMessage).ConfigureAwait(false); } _messageQueue.Add(applicationMessage); }
public async Task RemoveAsync(ManagedMqttApplicationMessage applicationMessage) { if (applicationMessage == null) throw new ArgumentNullException(nameof(applicationMessage)); using (await _messagesLock.WaitAsync(CancellationToken.None).ConfigureAwait(false)) { var index = _messages.IndexOf(applicationMessage); if (index == -1) { return; } _messages.RemoveAt(index); await SaveAsync().ConfigureAwait(false); } }
public async Task PublishAsync(ManagedMqttApplicationMessage applicationMessage) { if (applicationMessage == null) { throw new ArgumentNullException(nameof(applicationMessage)); } ManagedMqttApplicationMessage removedMessage = null; lock (_messageQueue) { if (_messageQueue.Count >= Options.MaxPendingMessages) { if (Options.PendingMessagesOverflowStrategy == MqttPendingMessagesOverflowStrategy.DropNewMessage) { _logger.Verbose("Skipping publish of new application message because internal queue is full."); ApplicationMessageSkipped?.Invoke(this, new ApplicationMessageSkippedEventArgs(applicationMessage)); return; } if (Options.PendingMessagesOverflowStrategy == MqttPendingMessagesOverflowStrategy.DropOldestQueuedMessage) { removedMessage = _messageQueue.RemoveFirst(); _logger.Verbose("Removed oldest application message from internal queue because it is full."); ApplicationMessageSkipped?.Invoke(this, new ApplicationMessageSkippedEventArgs(removedMessage)); } } _messageQueue.Enqueue(applicationMessage); } if (_storageManager != null) { if (removedMessage != null) { await _storageManager.RemoveAsync(removedMessage).ConfigureAwait(false); } await _storageManager.AddAsync(applicationMessage).ConfigureAwait(false); } }
public ApplicationMessageProcessedEventArgs(ManagedMqttApplicationMessage applicationMessage, Exception exception) { ApplicationMessage = applicationMessage ?? throw new ArgumentNullException(nameof(applicationMessage)); Exception = exception; }
public ApplicationMessageSkippedEventArgs(ManagedMqttApplicationMessage applicationMessage) { ApplicationMessage = applicationMessage ?? throw new ArgumentNullException(nameof(applicationMessage)); }