private void SendLastValue(Message msg) { var key = LabelWithoutPrefix(msg); if (string.IsNullOrWhiteSpace(msg.ResponseQueue)) { Console.Error.WriteLine($"INFO: Received a request for '{key}' without the response queue being set"); return; } var last = _cache[key]; if (last == null) { Console.Error.WriteLine($"DEBUG: there is no cached value for '{key}', sending an empty message"); last = new Message { Label = key }; } var replyQueue = _queueCache.Open(msg.ResponseQueue, QueueAccessMode.Send); last.CorrelationId = msg.Id; replyQueue.Write(last); Console.Error.WriteLine($"DEBUG: sent reply for '{key}' to {msg.ResponseQueue}"); // note: we do not wait for confirmation of delivery, we just report errors on via the AdminAsync (_adminTask) }
/// <summary>Read messages from the input queue and forward to subscribers</summary> async Task MulticastInputDispatcher() { await Task.Yield(); try { for (;;) { var msg = _inputReader.Read(Properties.All, TimeSpan.Zero) ?? await _inputReader.ReadAsync(Properties.All); // we could avoid the lock by using an immutable collection var subscribers = _subscriptions.GetSubscribers(msg.Label); if (subscribers.Count == 0) { continue; } var fn = string.Join(",", subscribers.Select(s => s.FormatName).Distinct()); // create a multi-element format name var q = _responseQueueCache.Open(fn, QueueAccessMode.Send); msg.AdministrationQueue = _adminQueueFormatName; q.Write(msg); } } catch (QueueException ex) when(ex.ErrorCode == ErrorCode.OperationCanceled) { // stopped } catch (ObjectDisposedException) { // stopped } catch (Exception ex) { Console.Error.WriteLine("ERROR MulticastInputDispatcher: " + ex); } }