/// <summary> /// Creates the queue of the name <paramref name="queueName"/> if it does not already exist, /// the queue is attached to <see cref="DequeuAndProcessCommand"/> using a <see cref="Thread"/>. /// </summary> /// <param name="queueName">The name of the queue to check and create.</param> protected void CreateQueueAndAttachListenerIfNotExist(string queueName) { if (!QueueTracker.ContainsKey(queueName)) { QueueTrackerLock.EnterWriteLock(); try { if (!QueueTracker.ContainsKey(queueName)) { QueueTracker.TryAdd(queueName, new ConcurrentQueue <ICommand <TAuthenticationToken> >()); new Thread(() => { Thread.CurrentThread.Name = queueName; DequeuAndProcessCommand(queueName); }).Start(); } } catch (Exception exception) { Logger.LogError(string.Format("Processing a request to start a thread for the queue '{0}' failed.", queueName), exception: exception); } finally { QueueTrackerLock.ExitWriteLock(); } } }
protected void DequeuAndProcessCommand(string queueName) { while (true) { try { ConcurrentQueue <ICommand <TAuthenticationToken> > queue; if (QueueTracker.TryGetValue(queueName, out queue)) { while (!queue.IsEmpty) { ICommand <TAuthenticationToken> command; if (queue.TryDequeue(out command)) { try { CorrelationIdHelper.SetCorrelationId(command.CorrelationId); } catch (Exception exception) { Logger.LogError(string.Format("Trying to set the CorrelationId from the command type {1} for a request for the queue '{0}' failed.", queueName, command.GetType()), exception: exception); } try { AuthenticationTokenHelper.SetAuthenticationToken(command.AuthenticationToken); } catch (Exception exception) { Logger.LogError(string.Format("Trying to set the AuthenticationToken from the command type {1} for a request for the queue '{0}' failed.", queueName, command.GetType()), exception: exception); } try { ReceiveCommand(command); } catch (Exception exception) { Logger.LogError(string.Format("Processing the command type {1} for a request for the queue '{0}' failed.", queueName, command.GetType()), exception: exception); queue.Enqueue(command); } } else { Logger.LogDebug(string.Format("Trying to dequeue a command from the queue '{0}' failed.", queueName)); } } } else { Logger.LogDebug(string.Format("Trying to find the queue '{0}' failed.", queueName)); } Thread.Sleep(100); } catch (Exception exception) { Logger.LogError(string.Format("Dequeuing and processing a request for the queue '{0}' failed.", queueName), exception: exception); } } }
/// <summary> /// Adds the provided <paramref name="command"/> to the <see cref="QueueTracker"/> of the queue <paramref name="targetQueueName"/>. /// </summary> private void EnqueueCommand(string targetQueueName, ICommand <TAuthenticationToken> command) { var queue = QueueTracker.GetOrAdd(targetQueueName, new ConcurrentQueue <ICommand <TAuthenticationToken> >()); queue.Enqueue(command); }
/// <summary> /// Takes an <see cref="IEvent{TAuthenticationToken}"/> off the queue of <paramref name="queueName"/> /// and calls <see cref="ReceiveEvent"/>. Repeats in a loop until the queue is empty. /// </summary> /// <param name="queueName">The name of the queue process.</param> protected void DequeuAndProcessEvent(string queueName) { SpinWait.SpinUntil ( () => { try { ConcurrentQueue <IEvent <TAuthenticationToken> > queue; if (QueueTracker.TryGetValue(queueName, out queue)) { while (!queue.IsEmpty) { IEvent <TAuthenticationToken> @event; if (queue.TryDequeue(out @event)) { try { CorrelationIdHelper.SetCorrelationId(@event.CorrelationId); } catch (Exception exception) { Logger.LogError(string.Format("Trying to set the CorrelationId from the event type {1} for a request for the queue '{0}' failed.", queueName, @event.GetType()), exception: exception); } try { AuthenticationTokenHelper.SetAuthenticationToken(@event.AuthenticationToken); } catch (Exception exception) { Logger.LogError(string.Format("Trying to set the AuthenticationToken from the event type {1} for a request for the queue '{0}' failed.", queueName, @event.GetType()), exception: exception); } try { ReceiveEvent(@event); } catch (Exception exception) { Logger.LogError(string.Format("Processing the event type {1} for a request for the queue '{0}' failed.", queueName, @event.GetType()), exception: exception); queue.Enqueue(@event); } } else { Logger.LogDebug(string.Format("Trying to dequeue a event from the queue '{0}' failed.", queueName)); } } } else { Logger.LogDebug(string.Format("Trying to find the queue '{0}' failed.", queueName)); } Thread.Sleep(100); } catch (Exception exception) { Logger.LogError(string.Format("Dequeuing and processing a request for the queue '{0}' failed.", queueName), exception: exception); } // Always return false to keep this spinning. return(false); }, sleepInMilliseconds: 1000 ); }
/// <summary> /// Adds the provided <paramref name="event"/> to the <see cref="QueueTracker"/> of the queue <paramref name="targetQueueName"/>. /// </summary> private void EnqueueEvent(string targetQueueName, IEvent <TAuthenticationToken> @event) { var queue = QueueTracker.GetOrAdd(targetQueueName, new ConcurrentQueue <IEvent <TAuthenticationToken> >()); queue.Enqueue(@event); }