internal ChannelQueue(Channel channel, ushort id, ChannelQueueOptions options, IMessageDeliveryHandler deliveryHandler) { Channel = channel; Id = id; Options = options; Status = options.Status; DeliveryHandler = deliveryHandler; State = QueueStateFactory.Create(this, options.Status); TimeKeeper = new QueueTimeKeeper(this); TimeKeeper.Run(); if (options.WaitForAcknowledge) { _ackSync = new SemaphoreSlim(1, 1); } _triggerTimer = new Timer(a => { if (!_triggering && State.TriggerSupported) { _ = Trigger(); } }, null, TimeSpan.FromSeconds(5000), TimeSpan.FromSeconds(5000)); }
/// <summary> /// Creates new queue in the channel with default handlers /// </summary> /// <exception cref="NoNullAllowedException">Thrown when server does not have default delivery handler implementation</exception> /// <exception cref="OperationCanceledException">Thrown when queue limit is exceeded for the channel</exception> /// <exception cref="DuplicateNameException">Thrown when there is already a queue with same id</exception> public async Task <ChannelQueue> CreateQueue(ushort queueId, Action <ChannelQueueOptions> optionsAction) { ChannelQueueOptions options = ChannelQueueOptions.CloneFrom(Options); optionsAction(options); return(await CreateQueue(queueId, options)); }
/// <summary> /// Creates new queue in the channel with default options and default handlers /// </summary> /// <exception cref="NoNullAllowedException">Thrown when server does not have default delivery handler implementation</exception> /// <exception cref="OperationCanceledException">Thrown when queue limit is exceeded for the channel</exception> /// <exception cref="DuplicateNameException">Thrown when there is already a queue with same id</exception> public async Task <ChannelQueue> CreateQueue(ushort queueId) { ChannelQueueOptions options = ChannelQueueOptions.CloneFrom(Options); return(await CreateQueue(queueId, options, Server.DefaultDeliveryHandler)); }
/// <summary> /// Creates new queue in the channel with default handlers /// </summary> /// <exception cref="NoNullAllowedException">Thrown when server does not have default delivery handler implementation</exception> /// <exception cref="OperationCanceledException">Thrown when queue limit is exceeded for the channel</exception> /// <exception cref="DuplicateNameException">Thrown when there is already a queue with same id</exception> public async Task <ChannelQueue> CreateQueue(ushort queueId, ChannelQueueOptions options) { if (DeliveryHandler == null) { throw new NoNullAllowedException("There is no default delivery handler defined for the channel. Queue must have it's own delivery handler."); } return(await CreateQueue(queueId, options, Server.DefaultDeliveryHandler)); }
/// <summary> /// Creates new queue in the channel /// </summary> /// <exception cref="NoNullAllowedException">Thrown when server does not have default delivery handler implementation</exception> /// <exception cref="OperationCanceledException">Thrown when queue limit is exceeded for the channel</exception> /// <exception cref="DuplicateNameException">Thrown when there is already a queue with same id</exception> public async Task <ChannelQueue> CreateQueue(ushort queueId, ChannelQueueOptions options, IMessageDeliveryHandler deliveryHandler) { if (deliveryHandler == null) { throw new NoNullAllowedException("Delivery handler cannot be null."); } //multiple queues are not allowed if (!Options.AllowMultipleQueues && _queues.Count > 0) { return(null); } //if content type is not allowed for this channel, return null if (Options.AllowedQueues != null && Options.AllowedQueues.Length > 0) { if (!Options.AllowedQueues.Contains(queueId)) { return(null); } } if (Options.QueueLimit > 0 && Options.QueueLimit >= _queues.Count) { throw new OperationCanceledException("Queue limit is exceeded for the channel"); } ChannelQueue queue = _queues.Find(x => x.Id == queueId); if (queue != null) { throw new DuplicateNameException($"The channel has already a queue with same content type: {queueId}"); } queue = new ChannelQueue(this, queueId, options, deliveryHandler); _queues.Add(queue); if (EventHandler != null) { await EventHandler.OnQueueCreated(queue, this); } return(queue); }
/// <summary> /// Applies non-null values to channel queue options /// </summary> public void ApplyToQueue(ChannelQueueOptions target) { if (SendOnlyFirstAcquirer.HasValue) { target.SendOnlyFirstAcquirer = SendOnlyFirstAcquirer.Value; } if (RequestAcknowledge.HasValue) { target.RequestAcknowledge = RequestAcknowledge.Value; } if (AcknowledgeTimeout.HasValue) { target.AcknowledgeTimeout = AcknowledgeTimeout.Value; } if (MessageTimeout.HasValue) { target.MessageTimeout = MessageTimeout.Value; } if (UseMessageId.HasValue) { target.UseMessageId = UseMessageId.Value; } if (WaitForAcknowledge.HasValue) { target.WaitForAcknowledge = WaitForAcknowledge.Value; } if (HideClientNames.HasValue) { target.HideClientNames = HideClientNames.Value; } if (Status.HasValue) { target.Status = Status.Value; } }
/// <summary> /// Creates new queue and sends response /// </summary> private async Task CreateQueue(MqClient client, TmqMessage message) { ushort?contentType; NetworkOptionsBuilder builder = null; if (message.Length == 2) { byte[] bytes = new byte[2]; await message.Content.ReadAsync(bytes); contentType = BitConverter.ToUInt16(bytes); } else { builder = new NetworkOptionsBuilder(); builder.Load(message.ToString()); contentType = builder.Id; } Channel channel = await CreateChannel(client, message, true); ChannelQueue queue = channel.FindQueue(contentType.Value); //if queue exists, we can't create. return duplicate response. if (queue != null) { if (message.ResponseRequired) { await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.Duplicate)); } return; } //check authority if client can create queue if (_server.Authorization != null) { bool grant = await _server.Authorization.CanCreateQueue(client, channel, contentType.Value, builder); if (!grant) { if (message.ResponseRequired) { await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.Unauthorized)); } return; } } //creates new queue ChannelQueueOptions options = ChannelQueueOptions.CloneFrom(channel.Options); IMessageDeliveryHandler delivery = channel.DeliveryHandler; if (builder != null) { builder.ApplyToQueue(options); if (!string.IsNullOrEmpty(builder.MessageDeliveryHandler)) { IMessageDeliveryHandler found = _server.Registry.GetMessageDelivery(builder.MessageDeliveryHandler); if (found != null) { delivery = found; } } } queue = await channel.CreateQueue(contentType.Value, options, delivery); //if creation successful, sends response if (queue != null && message.ResponseRequired) { await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.Ok)); } }