/// <summary>Restart the consumer.</summary> /// <param name="consumer">The consumer.</param> internal void Restart(BlockingQueueConsumer consumer) { lock (this.consumersMonitor) { if (this.consumers != null) { try { // Need to recycle the channel in this consumer consumer.Stop(); // Ensure consumer counts are correct (another is not going // to start because of the exception, but // we haven't counted down yet) this.cancellationLock.Release(consumer); this.consumers.Remove(consumer); consumer = this.CreateBlockingQueueConsumer(); this.consumers.Add(consumer); } catch (Exception e) { Logger.Warn(m => m("Consumer failed irretrievably on restart. {0}: {1}", e.Source, e.Message)); // Re-throw and have it logged properly by the caller. throw; } var processor = new AsyncMessageProcessingConsumer(consumer, this); var taskExecutor = new Task(processor.Run); taskExecutor.Start(); } } }
/// <summary>Receive and execute.</summary> /// <param name="consumer">The consumer.</param> /// <returns>True if a message was received.</returns> internal bool ReceiveAndExecute(BlockingQueueConsumer consumer) { if (this.transactionManager != null) { try { var transactionTemplate = new TransactionTemplate(this.transactionManager); transactionTemplate.PropagationBehavior = this.transactionAttribute.PropagationBehavior; transactionTemplate.TransactionIsolationLevel = IsolationLevel.Unspecified; // TODO: revert to transactionAttribute once we take dependency on SPRNET 2.0 transactionTemplate.TransactionTimeout = this.transactionAttribute.TransactionTimeout; transactionTemplate.ReadOnly = this.transactionAttribute.ReadOnly; transactionTemplate.Name = this.transactionAttribute.Name; return((bool)transactionTemplate.Execute( status => { ConnectionFactoryUtils.BindResourceToTransaction(new RabbitResourceHolder(consumer.Channel, false), this.ConnectionFactory, true); return this.DoReceiveAndExecute(consumer); })); } catch (Exception ex) { Logger.Error(m => m("Error receiving and executing."), ex); throw; } } return(this.DoReceiveAndExecute(consumer)); }
/// <summary>Perform receive and execute actions.</summary> /// <param name="consumer">The consumer.</param> /// <returns>True if a message was received.</returns> private bool DoReceiveAndExecute(BlockingQueueConsumer consumer) { var channel = consumer.Channel; for (var i = 0; i < this.txSize; i++) { Logger.Trace(m => m("Waiting for message from consumer.")); var message = consumer.NextMessage(this.receiveTimeout); if (message == null) { break; } try { this.ExecuteListener(channel, message); } catch (ImmediateAcknowledgeAmqpException e) { Logger.Trace(m => m("DoReceiveAndExecute => "), e); break; } catch (Exception ex) { consumer.RollbackOnExceptionIfNecessary(ex); throw; } } return(consumer.CommitIfNecessary(this.IsChannelLocallyTransacted(channel))); }
public void TestTransactionalLowLevel() { var template = new RabbitTemplate(); var connectionFactory = new CachingConnectionFactory(); connectionFactory.Port = BrokerTestUtils.GetPort(); template.ConnectionFactory = connectionFactory; var blockingQueueConsumer = new BlockingQueueConsumer(connectionFactory, new DefaultMessagePropertiesConverter(), new ActiveObjectCounter<BlockingQueueConsumer>(), AcknowledgeModeUtils.AcknowledgeMode.Auto, true, 1, queue.Name); blockingQueueConsumer.Start(); connectionFactory.Dispose(); // TODO: make this into a proper assertion. An exception can be thrown here by the Rabbit client and printed to // stderr without being rethrown (so hard to make a test fail). blockingQueueConsumer.Stop(); Assert.IsNull(template.ReceiveAndConvert(queue.Name)); }
private void TestRequeueOrNotDefaultNot(Exception ex, bool requeue) { var connectionFactory = new Mock<IConnectionFactory>(); var channel = new Mock<IModel>(); var blockingQueueConsumer = new BlockingQueueConsumer( connectionFactory.Object, new DefaultMessagePropertiesConverter(), new ActiveObjectCounter<BlockingQueueConsumer>(), AcknowledgeModeUtils.AcknowledgeMode.Auto, true, 1, false, "testQ"); this.TestRequeueOrNotGuts(ex, requeue, channel, blockingQueueConsumer); }
/// <summary>Initializes a new instance of the <see cref="InternalConsumer"/> class.</summary> /// <param name="channel">The channel.</param> /// <param name="outer">The outer.</param> public InternalConsumer(IModel channel, BlockingQueueConsumer outer) : base(channel) { this.outer = outer; }
/// <summary> /// Gets the result. /// </summary> /// <param name="consumer">The consumer.</param> /// <returns>The result.</returns> /// <remarks></remarks> private string GetResult(BlockingQueueConsumer consumer) { var response = consumer.NextMessage(new TimeSpan(0, 0, 0, 20)); if (response == null) { return null; } return (string)new SimpleMessageConverter().FromMessage(response); }
/// <summary> /// Creates the consumer. /// </summary> /// <param name="accessor">The accessor.</param> /// <returns>The consumer.</returns> /// <remarks></remarks> private BlockingQueueConsumer CreateConsumer(RabbitAccessor accessor) { var consumer = new BlockingQueueConsumer(accessor.ConnectionFactory, new ActiveObjectCounter<BlockingQueueConsumer>(), AcknowledgeModeUtils.AcknowledgeMode.AUTO, true, 1, 0, queue.Name); consumer.Start(); return consumer; }
/// <summary>Initializes a new instance of the <see cref="AsyncMessageProcessingConsumer"/> class.</summary> /// <param name="consumer">The consumer.</param> /// <param name="outer">The outer.</param> public AsyncMessageProcessingConsumer(BlockingQueueConsumer consumer, SimpleMessageListenerContainer outer) { this.consumer = consumer; this.outer = outer; this.start = new CountdownEvent(1); }
/// <summary>Receive and execute.</summary> /// <param name="consumer">The consumer.</param> /// <returns>True if a message was received.</returns> internal bool ReceiveAndExecute(BlockingQueueConsumer consumer) { if (this.transactionManager != null) { try { var transactionTemplate = new TransactionTemplate(this.transactionManager); transactionTemplate.PropagationBehavior = this.transactionAttribute.PropagationBehavior; transactionTemplate.TransactionIsolationLevel = IsolationLevel.Unspecified; // TODO: revert to transactionAttribute once we take dependency on SPRNET 2.0 transactionTemplate.TransactionTimeout = this.transactionAttribute.TransactionTimeout; transactionTemplate.ReadOnly = this.transactionAttribute.ReadOnly; transactionTemplate.Name = this.transactionAttribute.Name; return (bool)transactionTemplate.Execute( status => { ConnectionFactoryUtils.BindResourceToTransaction(new RabbitResourceHolder(consumer.Channel, false), this.ConnectionFactory, true); return this.DoReceiveAndExecute(consumer); }); } catch (Exception ex) { Logger.Error(m => m("Error receiving and executing."), ex); throw; } } return this.DoReceiveAndExecute(consumer); }
/// <summary> /// Perform receive and execute actions. /// </summary> /// <param name="consumer"> /// The consumer. /// </param> /// <returns> /// True if a message was received. /// </returns> private bool DoReceiveAndExecute(BlockingQueueConsumer consumer) { var channel = consumer.Channel; Message lastMessage = null; for (var i = 0; i < this.txSize; i++) { this.logger.Trace("Waiting for message from consumer."); var message = consumer.NextMessage(new TimeSpan(0, 0, 0, 0, (int)this.receiveTimeout)); if (message == null) { break; } lastMessage = message; try { this.ExecuteListener(channel, message); } catch (ImmediateAcknowledgeAmqpException e) { break; } catch (Exception ex) { this.RollbackOnExceptionIfNecessary(channel, message, ex); throw; } } if (lastMessage != null) { this.CommitIfNecessary(channel, lastMessage); return true; } return false; }
private void TestRequeueOrNotGuts(Exception ex, bool requeue, Mock<IModel> channel, BlockingQueueConsumer blockingQueueConsumer) { var channelField = typeof(BlockingQueueConsumer).GetField("channel", BindingFlags.NonPublic | BindingFlags.Instance); channelField.SetValue(blockingQueueConsumer, channel.Object); var deliveryTags = new LinkedList<long>(); deliveryTags.AddOrUpdate(1L); var deliveryTagsField = typeof(BlockingQueueConsumer).GetField("deliveryTags", BindingFlags.NonPublic | BindingFlags.Instance); deliveryTagsField.SetValue(blockingQueueConsumer, deliveryTags); blockingQueueConsumer.RollbackOnExceptionIfNecessary(ex); channel.Verify(m => m.BasicReject(1L, requeue), Times.Once()); }
/// <summary> /// Restart the consumer. /// </summary> /// <param name="consumer"> /// The consumer. /// </param> /// <exception cref="Exception"> /// </exception> internal void Restart(BlockingQueueConsumer consumer) { lock (this.consumersMonitor) { if (this.consumers != null) { try { // Need to recycle the channel in this consumer consumer.Stop(); // Ensure consumer counts are correct (another is not going // to start because of the exception, but // we haven't counted down yet) this.cancellationLock.Release(consumer); this.consumers.Remove(consumer); consumer = this.CreateBlockingQueueConsumer(); this.consumers.Add(consumer); } catch (Exception e) { this.logger.Warn("Consumer died on restart. " + e.Source + ": " + e.Message); // Thrown into the void (probably) in a background thread. // Oh well, here goes... throw e; } this.taskExecutor.Execute(new AsyncMessageProcessingConsumer(consumer, this)); } } }
/// <summary> /// Receive and execute. /// </summary> /// <param name="consumer"> /// The consumer. /// </param> /// <returns> /// True if a message was received. /// </returns> internal bool ReceiveAndExecute(BlockingQueueConsumer consumer) { if (this.transactionManager != null) { try { return (bool)new TransactionTemplate(this.transactionManager).Execute(delegate(ITransactionStatus status) { ConnectionFactoryUtils.BindResourceToTransaction(new RabbitResourceHolder(consumer.Channel), this.ConnectionFactory, true); try { return this.DoReceiveAndExecute(consumer); } catch (Exception e) { throw; } }); } catch (Exception e) { throw; } } return this.DoReceiveAndExecute(consumer); }
/// <summary> /// Initializes a new instance of the <see cref="AsyncMessageProcessingConsumer"/> class. /// </summary> /// <param name="consumer"> /// The consumer. /// </param> /// <param name="outer"> /// The outer. /// </param> public AsyncMessageProcessingConsumer(BlockingQueueConsumer consumer, SimpleMessageListenerContainer outer) { this.consumer = consumer; this.outer = outer; this.start = new CountDownLatch(1); }
/// <summary>Creates the consumer.</summary> /// <param name="accessor">The accessor.</param> /// <returns>The consumer.</returns> private BlockingQueueConsumer CreateConsumer(RabbitAccessor accessor) { var consumer = new BlockingQueueConsumer(accessor.ConnectionFactory, new DefaultMessagePropertiesConverter(), new ActiveObjectCounter<BlockingQueueConsumer>(), AcknowledgeModeUtils.AcknowledgeMode.Auto, true, 1, queue.Name); consumer.Start(); // wait for consumeOk... var n = 0; while (n++ < 100) { if (consumer.ConsumerTag == null) { try { Thread.Sleep(100); } catch (ThreadInterruptedException e) { Thread.CurrentThread.Interrupt(); break; } } } return consumer; }
/// <summary>Perform receive and execute actions.</summary> /// <param name="consumer">The consumer.</param> /// <returns>True if a message was received.</returns> private bool DoReceiveAndExecute(BlockingQueueConsumer consumer) { var channel = consumer.Channel; for (var i = 0; i < this.txSize; i++) { Logger.Trace(m => m("Waiting for message from consumer.")); var message = consumer.NextMessage(this.receiveTimeout); if (message == null) { break; } try { this.ExecuteListener(channel, message); } catch (ImmediateAcknowledgeAmqpException e) { Logger.Trace(m => m("DoReceiveAndExecute => "), e); break; } catch (Exception ex) { consumer.RollbackOnExceptionIfNecessary(ex); throw; } } return consumer.CommitIfNecessary(this.IsChannelLocallyTransacted(channel)); }
/// <summary> /// Initializes a new instance of the <see cref="InternalConsumer"/> class. /// </summary> /// <param name="channel"> /// The channel. /// </param> /// <param name="outer"> /// The outer. /// </param> public InternalConsumer(IModel channel, BlockingQueueConsumer outer) : base(channel) { this.outer = outer; }