/// <summary> /// Invoked when the internally used timer elapses /// </summary> /// <param name="sender">A <see cref="object" /> representation of the <see cref="ITimer" /> raising the event</param> /// <param name="e">The <see cref="EventArgs" /> instance containing the event data</param> private void OnTimerElapsed(object sender, EventArgs e) { while (!_msgQueue.IsEmpty) { if (!_connectionStatus.IsConnected) { break; } PublishQueueItem pqi = null; try { if (_msgQueue.TryDequeue(out pqi)) { //check if expired if (pqi.Timestamp < DateTime.Now.AddMilliseconds(-_queueTimeout)) { var msg = $"At {DateTime.Now} publishing queue item is expired. CorrelationId={pqi.CorrelationId}, RoutingKey={pqi.RoutingKey}, Added={pqi.Timestamp}."; ExecutionLog.LogError(msg); FeedLog.LogError(msg); RaiseMessagePublishFailedEvent(pqi.Message, pqi.CorrelationId, pqi.RoutingKey, "Queue item is expired."); continue; } //publish var publishResult = PublishMsg(pqi.TicketId, (byte[])pqi.Message, pqi.RoutingKey, pqi.CorrelationId, pqi.ReplyRoutingKey); if (publishResult.IsSuccess) { if (FeedLog.IsEnabled(LogLevel.Debug)) { FeedLog.LogDebug($"Publish succeeded. CorrelationId={pqi.CorrelationId}, RoutingKey={pqi.RoutingKey}, ReplyRoutingKey={pqi.ReplyRoutingKey}, Added={pqi.Timestamp}."); } else { FeedLog.LogInformation($"Publish succeeded. CorrelationId={pqi.CorrelationId}, RoutingKey={pqi.RoutingKey}, Added={pqi.Timestamp}."); } } else { FeedLog.LogWarning($"Publish failed. CorrelationId={pqi.CorrelationId}, RoutingKey={pqi.RoutingKey}, Added={pqi.Timestamp}. Reason={publishResult.Message}"); RaiseMessagePublishFailedEvent(pqi.Message, pqi.CorrelationId, pqi.RoutingKey, publishResult.Message); } } } catch (Exception exception) { FeedLog.LogError($"Error during publishing queue item. CorrelationId={pqi?.CorrelationId}, RoutingKey={pqi?.RoutingKey}, Added={pqi?.Timestamp}.", exception); if (pqi != null) { RaiseMessagePublishFailedEvent(pqi.Message, pqi.CorrelationId, pqi.RoutingKey, "Error during publishing queue item: " + exception); } } } if (_useQueue) { _queueTimer.FireOnce(TimeSpan.FromMilliseconds(200)); // recheck after X milliseconds } }
/// <summary> /// Adds to publishing queue /// </summary> /// <param name="ticketId">Ticket Id</param> /// <param name="msg">The MSG</param> /// <param name="routingKey">The routing key</param> /// <param name="correlationId">The correlation identifier</param> /// <param name="replyRoutingKey">The reply routing key</param> /// <returns>IMqPublishResult</returns> private IMqPublishResult AddToPublishingQueue(string ticketId, byte[] msg, string routingKey, string correlationId, string replyRoutingKey) { var item = new PublishQueueItem(ticketId, msg, routingKey, correlationId, replyRoutingKey); if (_queueLimit > 0 && _msgQueue.Count >= _queueLimit) { var errorMessage = $"Publishing Queue is full. CorrelationId={correlationId}, RoutingKey={routingKey}."; FeedLog.LogError(errorMessage); ExecutionLog.LogError(errorMessage); //since user called Publish, we just return result and no need to call event handler //var args = new MessagePublishFailedEventArgs(msg, correlationId, routingKey, errorMessage); //MqMessagePublishFailed?.Invoke(this, args); return(new MqPublishResult(correlationId, false, errorMessage)); } _msgQueue.Enqueue(item); FeedLog.LogDebug($"Message with correlationId:{correlationId} and routingKey:{routingKey} added to publishing queue."); return(new MqPublishResult(correlationId, true, "Item added to publishing queue.")); }