public Task Consume(ConsumeContext <IAccountSequenceCompletedEvent> context) { try { using (var channel = _connection.CreateModel()) { var address = new Uri(context.Message.QueueAddress); var queueName = address.Segments.Last(); var queue = channel.QueueDeclarePassive(queueName); if (queue.MessageCount == 0) { if (Program.Queues.ContainsKey(context.Message.QueueAddress)) { lock (Lock.SyncRoot) { DeleteQueue(context.Message.QueueAddress); string queueAddress; while (Program.Queues.TryRemove(context.Message.QueueAddress, out queueAddress) == false) { } } } } else { //var busHostUri = _appSettings["busHostUri"]; //var workerQueueName = _appSettings["workerQueueName"]; //var workerQueueUri = new Uri($"{busHostUri}/{workerQueueName}"); try { _accountSequenceNotifier.NotifyWorkers(context, context.Message.QueueAddress).Wait(); } catch (Exception ex) { Console.WriteLine(ex.Message); throw; } } channel.Close(200, "Ok"); } return(Task.Factory.StartNew(() => _console.WriteLine($"{context.Message.QueueAddress}"))); } catch (Exception ex) { _console.WriteLine("AccountSequenceCompletedEventConsumer::" + ex.Message); throw; } }
public Task Consume(ConsumeContext <IADTCommand> context) { try { var delay = (DateTime.Now - context.Message.Timestamp).TotalMilliseconds.Rounded(); var stopwatch = new Stopwatch(); stopwatch.Start(); _console.WriteLine($"{context.Message.FacilityId}-{context.Message.AccountNumber}"); var busHostUri = _appSettings["busHostUri"]; var routerQueueName = _appSettings["routerQueueName"]; var key = GetKey(context.Message); var endpointAddressUrl = $"{busHostUri}/{routerQueueName}.{key}"; bool queueDoesNotExist; //NOTE: Sad case - worker tries to read from a queue that was just deleted after sequence command was sent. // Had to increase the lock because the worker started having issues trying to read from a queue that had been deleted. May want to do this as a single thread // that processes both types of messages so that there is no need for synchronization. //NOTE: Would like to limit this lock, by only locking for creation of queue and send to temporary queue...the rest can remain outside of that. lock (Lock.SyncRoot) { queueDoesNotExist = Program.Queues.ContainsKey(endpointAddressUrl) == false; if (queueDoesNotExist) { //lock (Lock.SyncRoot) //{ //NOTE: Sad case - delete queue before publish to bound queue // Originally, put a lock around just the bind and around the delete to make sure that a queue doesn't get deleted and you try to publish to it. BindQueue(endpointAddressUrl); //} } var endpointUri = new Uri(endpointAddressUrl); //NOTE: Should we update the timestamp or just measure from the first time the message was inserted? //context.Message.Timestamp = DateTime.Now; context .Send(endpointUri, context.Message).Wait(); } if (queueDoesNotExist) { //var workerQueueName = _appSettings["workerQueueName"]; //var workerQueueUri = new Uri($"{busHostUri}/{workerQueueName}"); _accountSequenceNotifier.NotifyWorkers(context, endpointAddressUrl).Wait(); while (Program.Queues.TryAdd(endpointAddressUrl, endpointAddressUrl) == false) { } } stopwatch.Stop(); var execution = stopwatch.Elapsed.TotalMilliseconds.Rounded(); return(context .Publish <IMetricsEvent>( new MetricsEvent() { EventType = routerQueueName, DelayInMilliseconds = delay, ExecutionInMilliseconds = execution, Successful = true })); } catch (Exception ex) { _console.WriteLine("RoutedADTCommandConsumer::" + ex.Message); throw; } }