示例#1
0
        internal async Task <HorseQueue> CreateQueue(string queueName,
                                                     QueueOptions options,
                                                     HorseMessage requestMessage,
                                                     Func <DeliveryHandlerBuilder, Task <IMessageDeliveryHandler> > asyncHandler,
                                                     bool hideException,
                                                     bool returnIfExists)
        {
            await _createQueueLocker.WaitAsync();

            try
            {
                if (!Filter.CheckNameEligibility(queueName))
                {
                    throw new InvalidOperationException("Invalid queue name");
                }

                if (Options.QueueLimit > 0 && Options.QueueLimit >= _queues.Count)
                {
                    throw new OperationCanceledException("Queue limit is exceeded for the server");
                }

                HorseQueue queue = _queues.Find(x => x.Name == queueName);

                if (queue != null)
                {
                    if (returnIfExists)
                    {
                        return(queue);
                    }

                    throw new DuplicateNameException($"The server has already a queue with same name: {queueName}");
                }

                string topic           = null;
                bool   statusSpecified = false; //when queue is created by subscriber, it will be initialized if status is specified
                if (requestMessage != null)
                {
                    string waitForAck = requestMessage.FindHeader(HorseHeaders.ACKNOWLEDGE);
                    if (!string.IsNullOrEmpty(waitForAck))
                    {
                        switch (waitForAck.Trim().ToLower())
                        {
                        case "none":
                            options.Acknowledge = QueueAckDecision.None;
                            break;

                        case "request":
                            options.Acknowledge = QueueAckDecision.JustRequest;
                            break;

                        case "wait":
                            options.Acknowledge = QueueAckDecision.WaitForAcknowledge;
                            break;
                        }
                    }

                    string queueStatus = requestMessage.FindHeader(HorseHeaders.QUEUE_STATUS);
                    if (queueStatus != null)
                    {
                        statusSpecified = true;
                        options.Status  = QueueStatusHelper.FindStatus(queueStatus);
                    }

                    topic = requestMessage.FindHeader(HorseHeaders.QUEUE_TOPIC);

                    string delay = requestMessage.FindHeader(HorseHeaders.DELAY_BETWEEN_MESSAGES);
                    if (!string.IsNullOrEmpty(delay))
                    {
                        options.DelayBetweenMessages = Convert.ToInt32(delay);
                    }
                }

                queue = new HorseQueue(this, queueName, options);
                if (!string.IsNullOrEmpty(topic))
                {
                    queue.Topic = topic;
                }

                DeliveryHandlerBuilder handlerBuilder = new DeliveryHandlerBuilder
                {
                    Server = this,
                    Queue  = queue
                };
                if (requestMessage != null)
                {
                    handlerBuilder.DeliveryHandlerHeader = requestMessage.FindHeader(HorseHeaders.DELIVERY_HANDLER);
                    handlerBuilder.Headers = requestMessage.Headers;
                }

                bool initialize;
                //if queue creation is triggered by consumer subscription, we might skip initialization
                if (requestMessage != null && requestMessage.Type == MessageType.Server && requestMessage.ContentType == KnownContentTypes.Subscribe)
                {
                    initialize = statusSpecified;
                }
                else
                {
                    initialize = true;
                }

                if (initialize)
                {
                    IMessageDeliveryHandler deliveryHandler = await asyncHandler(handlerBuilder);

                    queue.InitializeQueue(deliveryHandler);
                }

                _queues.Add(queue);
                foreach (IQueueEventHandler handler in _queueEventHandlers)
                {
                    await handler.OnCreated(queue);
                }

                if (initialize)
                {
                    handlerBuilder.TriggerAfterCompleted();
                }

                OnQueueCreated.Trigger(queue);
                return(queue);
            }
            catch (Exception e)
            {
                SendError("CREATE_QUEUE", e, $"QueueName:{queueName}");

                if (!hideException)
                {
                    throw;
                }

                return(null);
            }
            finally
            {
                try
                {
                    _createQueueLocker.Release();
                }
                catch
                {
                }
            }
        }