public async Task <IActiveConsumer> StartListeningQueueAsync <T>(string queueName, ConsumerOptions <T> consumerOptions, ProcessorMessageDelegate <T> messageProcessor) where T : class { var activeMessageProcessorCanceller = new ActiveMessageProcessorCanceller(); const string consumerTagKey = "consumerTag"; var pipeContext = new ClientPipeContextAction((channel, context) => { var consumerTag = BeginConsumeQueue(channel, queueName, consumerOptions, messageProcessor, activeMessageProcessorCanceller); context.Items[consumerTagKey] = consumerTag; return(Task.CompletedTask); }); await ClientPipe.ExecutePipelineAsync(pipeContext, _consumerPipeline.Value); return(new ActiveConsumer(pipeContext.GetItemValue <string>(consumerTagKey), pipeContext.ChannelContainer !, activeMessageProcessorCanceller)); }
// create new class that handle all cancel Logic: (Create pipe too) // - Immediate cancel: Cancel token given to the pipeline, and wait it to leave (catch in finally ?) // - Do not cancel token, but when it's been cancelled, if a task is in progress then it should wait the task to complete. private string BeginConsumeQueue <T>( IModel channel, string queueName, ConsumerOptions <T> consumerOptions, ProcessorMessageDelegate <T> messageProcessor, ActiveMessageProcessorCanceller activeMessageProcessorCanceller ) where T : class { var consumer = new AsyncEventingBasicConsumer(channel); consumer.Received += async(_, message) => { var consumerPipeContext = new ConsumerPipeContext <T>(_options.RabbitMqConnectionManager, channel, message, messageProcessor, activeMessageProcessorCanceller); await ConsumerPipe <T> .ExecutePipelineAsync(consumerPipeContext, consumerOptions.BuildPipeline()); }; if (consumerOptions.PrefetchCount.HasValue) { channel.BasicQos(0, consumerOptions.PrefetchCount.Value, false); } return(channel.BasicConsume(queueName, false, consumer)); }