void EnsureConsumerInitialized() { // if the consumer is null at this point, we see if we can initialize it... if (_consumer == null) { lock (_consumerInitializationLock) { // if there is a consumer instance at this point, someone else went and initialized it... if (_consumer == null) { try { _consumer = InitializeConsumer(); } catch (OperationInterruptedException objectInterruptedException) when(objectInterruptedException.Message.Contains("code=404, text=\"NOT_FOUND - no queue")) { _log.Warn("Queue not found - attempting to recreate queue and restore subscriptions."); ReconnectQueue(); _consumer = InitializeConsumer(); } catch (Exception exception) { _log.Warn("Could not initialize consumer: {0} - waiting 2 seconds", exception); Thread.Sleep(2000); } } } } }
void ClearConsumer() { var currentConsumer = _consumer; _consumer = null; if (currentConsumer == null) { return; } try { currentConsumer.Model.Dispose(); } catch { } }
/// <summary> /// Creates the consumer. /// </summary> CustomQueueingConsumer InitializeConsumer() { IConnection connection = null; IModel model = null; try { // receive must be done with separate model connection = _connectionManager.GetConnection(); model = connection.CreateModel(); model.BasicQos(0, _maxMessagesToPrefetch, false); var consumer = new CustomQueueingConsumer(model); model.BasicConsume(Address, false, consumer); _log.Info("Successfully initialized consumer for {queueName}", Address); return(consumer); } catch (OperationInterruptedException objectInterruptedException) when(objectInterruptedException.Message.Contains("code=404, text=\"NOT_FOUND - no queue")) { _log.Warn("Queue not found - attempting to recreate queue and restore subscriptions."); ReconnectQueue(); return(null); } catch (Exception) { try { model?.Dispose(); } catch { } try { connection?.Dispose(); } catch { } throw; } }
/// <summary> /// Creates the consumer. /// </summary> CustomQueueingConsumer InitializeConsumer() { IConnection connection = null; IModel model = null; try { // receive must be done with separate model connection = _connectionManager.GetConnection(); model = connection.CreateModel(); model.BasicQos(0, _maxMessagesToPrefetch, false); var consumer = new CustomQueueingConsumer(model); model.BasicConsume(Address, false, consumer); _log.Info("Successfully initialized consumer for {0}", Address); return(consumer); } catch (Exception) { try { model?.Dispose(); } catch { } try { connection?.Dispose(); } catch { } throw; } }
void EnsureConsumerInitialized() { // if the consumer is null at this point, we see if we can initialize it... if (_consumer == null) { lock (_consumerInitializationLock) { // if there is a consumer instance at this point, someone else went and initialized it... if (_consumer == null) { try { _consumer = InitializeConsumer(); } catch (Exception exception) { _log.Warn("Could not initialize consumer: {0} - waiting 2 seconds", exception); Thread.Sleep(2000); } } } } }
/// <inheritdoc /> public async Task <TransportMessage> Receive(ITransactionContext context, CancellationToken cancellationToken) { if (Address == null) { throw new InvalidOperationException("This RabbitMQ transport does not have an input queue - therefore, it is not possible to reveive anything"); } try { EnsureConsumerInitialized(); var consumer = _consumer; // initialization must have failed if (consumer == null) { return(null); } var model = consumer.Model; if (!model.IsOpen) { // something is wrong - we would not be able to ACK messages - force re-initialization to happen _consumer = null; // try to get rid of the consumer we have here try { model.Dispose(); } catch { } } BasicDeliverEventArgs result; if (!consumer.Queue.Dequeue(TwoSeconds, out result)) { return(null); } var deliveryTag = result.DeliveryTag; context.OnCommitted(async() => { model.BasicAck(deliveryTag, false); }); context.OnAborted(() => { // we might not be able to do this, but it doesn't matter that much if it succeeds try { model.BasicNack(deliveryTag, false, true); } catch { } }); return(CreateTransportMessage(result.BasicProperties, result.Body)); } catch (EndOfStreamException exception) { ClearConsumer(); throw new RebusApplicationException(exception, "Queue throw EndOfStreamException(meaning it was canceled by rabbitmq)"); } catch (Exception exception) { ClearConsumer(); Thread.Sleep(1000); throw new RebusApplicationException(exception, $"unexpected exception thrown while trying to dequeue a message from rabbitmq, queue address: {Address}"); } }