title: All messages in queue get allocated to a single subscriber
body: <p>I have sent some 10000 messages to a persistent RabbitMQ queue, all these messages are in &quot;Ready&quot; state. The code below sleeps for 10 seconds when processing each message. As soon as I run the rust application that calls the function below, all these messages in the queue have their status moved from &quot;Ready&quot; to &quot;Unacked&quot; almost instantly. The code continues to process the messages one message at a time.</p>
  <p>If I start another instance of that runs the code below, no messages are dispatched to this instance unless I terminate the first application.</p>
  <p>The behaviour I would like to have is subscribers at most only receive one message at a time and only get to obtain the next message once they've acked the current one.</p>
  <p>What configuration should I change?</p>
  <pre><code>use lapin::{options::*, Connection, ConnectionProperties, Result};
  use futures_util::stream::StreamExt;
  //use std::future::Future;
  use tracing::info;
  use slog::Drain;
  
  pub fn lapin_test_consumer()-&gt;std::result::Result&lt;i64, Box&lt;std::io::Error&gt;&gt; {
      //env_logger::init();
      let log_file_name:&amp;str=&quot;/tmp/lapin_test_consumer.log&quot;;
      let log_file_path=std::path::Path::new(&amp;log_file_name);
      let dir_file_path=log_file_path.parent().unwrap();
      std::fs::create_dir_all(dir_file_path).unwrap();
      
      let log_file_handler_option = std::fs::OpenOptions::new()
          .create(true)
          .write(true)
          .truncate(true)
          .open(log_file_name)
          //.unwrap()
      ;
      let log_file_handler=match log_file_handler_option
      {
          Ok(f)=&gt;f
          ,Err(err)=&gt;{
              println!(&quot;{:?}&quot;, err);
              panic!(&quot;Unable to open the log file '{}', '{:?}'&quot;,log_file_name,err);
          }
      };
      
      let my_log_drain = slog_async::Async::new(
          slog::Duplicate::new(
              slog::Filter::new(
                  slog_term::FullFormat::new(
                      slog_term::PlainSyncDecorator::new(log_file_handler,)
                  )
                  .use_file_location()
                  .build()
                  ,
                  |record: &amp;slog::Record|
                  {
                      record.level().is_at_least(slog::Level::Debug)
                  }    
              )
              //,slog_term::FullFormat::new(slog_term::PlainSyncDecorator::new(std::io::stdout())).build()
              ,slog::Duplicate::new(
                  slog::Filter::new(
                      slog_term::FullFormat::new(
                          slog_term::PlainSyncDecorator::new(std::io::stderr(),)
                      )
                      .use_file_location()
                      .build()
                      ,
                      //|record: &amp;slog::Record| record.level().is_at_least(slog::Level::Warning)
                      |record: &amp;slog::Record|
                      {
                          record.level().is_at_least(slog::Level::Debug)
                      }    
                      
                  )
                  //,slog_term::FullFormat::new(slog_term::PlainSyncDecorator::new(std::io::stdout())).build()
                  ,slog_term::FullFormat::new(slog_term::TermDecorator::new().build()).use_file_location().build()
              )
          ).fuse()
      )
      .build()
      .fuse()
      ;
      let my_slog_logger=slog::Logger::root(my_log_drain, slog::o!(&quot;n&quot; =&gt; env!(&quot;CARGO_PKG_NAME&quot;),&quot;v&quot; =&gt; env!(&quot;CARGO_PKG_VERSION&quot;)));
      
      if std::env::var(&quot;RUST_LOG&quot;).is_err() {
          std::env::set_var(&quot;RUST_LOG&quot;, &quot;info&quot;);
      }
  
  
      let addr:String = std::env::var(&quot;AMQP_ADDR&quot;).unwrap_or_else(
          |_|{
              format!(&quot;amqp://{}:{}@{}:{}/{}?heartbeat=0&quot;
                  ,&quot;abcd&quot;//aMQPJobUser
                  ,&quot;abcd&quot;//aMQPJobPasswd
                  ,&quot;somewhere.com&quot;//aMQPJobHost
                  ,5672//aMQPJobPort
                  ,&quot;lapin_test.test&quot;//aMQPJobVirtualHost
              ).into()
          }
      );
      let amqp_conn_url:&amp;str=&amp;addr.as_str();
      
  
      //see &quot;https://docs.rs/lapin/1.8.0/lapin/struct.Consumer.html&quot;
      let res: std::result::Result&lt;i64, Box&lt;std::io::Error&gt;&gt; = async_global_executor::block_on(async {
              let sleep_duration_ms:u64=10000u64;
              let conn_result:std::result::Result&lt;lapin::Connection, lapin::Error&gt; = Connection::connect(
                  &amp;amqp_conn_url,
                  ConnectionProperties::default().with_default_executor(2),//set the number of threads
              )
              .await;
              let conn:lapin::Connection=match conn_result{
                  Err(err)=&gt;{
                      let bt=backtrace::Backtrace::new();
                      let log_message=format!(&quot;&gt;&gt;&gt;&gt;&gt;At lapin_test_publisher(), pos 1b, some error has been encountered while trying to establish AMQP connection '{:?}', error is:'{:?}', backtrace is '{:?}'&quot;,&amp;amqp_conn_url,&amp;err,&amp;bt);
                      slog::error!(my_slog_logger,&quot;{}&quot;,log_message);
                      let custom_error=std::io::Error::new(std::io::ErrorKind::Other, &amp;log_message.to_string()[..]);
                      return std::result::Result::Err(Box::new(custom_error));
                  }
                  Ok(conn2)=&gt;{info!(&quot;CONNECTED&quot;);conn2}
              };
              
              
              let mut message_cnt:i64=0i64;let _some_i64:i64=message_cnt;
              let channel_a_result:Result&lt;lapin::Channel&gt;=conn.create_channel().await;
              let channel_a:lapin::Channel=match channel_a_result{
                  Err(err)=&gt;{
                      let bt=backtrace::Backtrace::new();
                      let log_message=format!(&quot;&gt;&gt;&gt;&gt;&gt;At lapin_test_consumer(), pos 1b, some error has been encountered while trying to obtain a channel from AMQP connection '{:?}', error is:'{:?}', backtrace is '{:?}'&quot;,&amp;amqp_conn_url,&amp;err,&amp;bt);
                      slog::error!(my_slog_logger,&quot;{}&quot;,log_message);
                      let custom_error=std::io::Error::new(std::io::ErrorKind::Other, &amp;log_message.to_string()[..]);
                      return std::result::Result::Err(Box::new(custom_error));
                  }
                  Ok(channel)=&gt;{channel}
              };
              
              channel_a
                  .exchange_declare(
                      &quot;my_direct_exchange&quot;
                      ,lapin::ExchangeKind::Direct
                      ,lapin::options::ExchangeDeclareOptions{
                          passive:false
                          ,durable:true
                          ,auto_delete:false
                          ,internal:false
                          ,nowait:false
                      }
                      ,lapin::types::FieldTable::default()//see &quot;https://docs.rs/amq-protocol-types/6.1.0/amq_protocol_types/struct.FieldTable.html&quot;
                  )
              ;
              
              let queue = channel_a
                  .queue_declare(
                      &quot;hello.persistent&quot;//:&amp;str queue name
                      ,lapin::options::QueueDeclareOptions{
                          passive:false,
                          durable:true,
                          exclusive:false,
                          auto_delete:false,
                          nowait:false,
                      }
                      ,lapin::types::FieldTable::default()//see &quot;https://docs.rs/amq-protocol-types/6.1.0/amq_protocol_types/struct.FieldTable.html&quot;
                  )
                  .await
                  .expect(&quot;queue_declare&quot;)
              ;
              channel_a
                  .queue_bind(
                      &quot;hello.persistent&quot;
                      ,&quot;my_direct_exchange&quot;
                      ,&quot;hello.persistent&quot;
                      , lapin::options::QueueBindOptions{
                          nowait:false
                      }
                      ,lapin::types::FieldTable::default()//see &quot;https://docs.rs/amq-protocol-types/6.1.0/amq_protocol_types/struct.FieldTable.html&quot;
                  )
              ;
              
              let consumer_a_result:Result&lt;lapin::Consumer&gt;=channel_a
                  .basic_consume(
                      &quot;hello.persistent&quot;,
                      &quot;my_consumer&quot;,
                      lapin::options::BasicConsumeOptions{
                          no_local: true,//see &quot;https://www.rabbitmq.com/amqp-0-9-1-reference.html#domain.no-local&quot;
                          no_ack: false,//see &quot;https://www.rabbitmq.com/amqp-0-9-1-reference.html#domain.no-ack&quot; &quot;If this field is set the server does not expect acknowledgements for messages. That is, when a message is delivered to the client the server assumes the delivery will succeed and immediately dequeues it. This functionality may increase performance but at the cost of reliability. Messages can get lost if a client dies before they are delivered to the application.&quot;
                          exclusive: false,
                          nowait: false,//see &quot;https://www.rabbitmq.com/amqp-0-9-1-reference.html#domain.no-wait&quot; &quot;If set, the server will not respond to the method. The client should not wait for a reply method. If the server could not complete the method it will raise a channel or connection exception.&quot;
                      },
                      lapin::types::FieldTable::default(),
                  )
                  .await;
              let mut consumer_a:lapin::Consumer=match consumer_a_result{
                  Err(err)=&gt;{
                      let bt=backtrace::Backtrace::new();
                      let log_message=format!(&quot;&gt;&gt;&gt;&gt;&gt;At lapin_test_consumer(), pos 1b, some error has been encountered while trying to obtain a consumer from AMQP connection '{:?}', error is:'{:?}', backtrace is '{:?}'&quot;,&amp;amqp_conn_url,&amp;err,&amp;bt);
                      slog::error!(my_slog_logger,&quot;{}&quot;,log_message);
                      let custom_error=std::io::Error::new(std::io::ErrorKind::Other, &amp;log_message.to_string()[..]);
                      return std::result::Result::Err(Box::new(custom_error));
                      //return Err(err);
                  }
                  Ok(consumer)=&gt;{consumer}
              };
          
              while let Some(delivery) = consumer_a.next().await {
                  let (channel2, delivery2) = delivery.expect(&quot;error in consumer&quot;);
                  message_cnt+=1;
                  slog::info!(my_slog_logger,&quot;------------------------------------------------------------------, message_cnt is:{}&quot;,&amp;message_cnt);
                  let s:String = match String::from_utf8(delivery2.data.to_owned()) {//delivery.data is of type Vec&lt;u8&gt;
                      Ok(v) =&gt; v,
                      Err(e) =&gt; panic!(&quot;Invalid UTF-8 sequence: {}&quot;, e),
                  };          
                  let log_message:String=format!(&quot;message_cnt is:{}, delivery_tag is:{}, exchange is:{}, routing_key is:{}, redelivered is:{}, properties is:'{:?}', received data is:'{:?}'&quot;
                      ,&amp;message_cnt
                      ,&amp;delivery2.delivery_tag
                      ,&amp;delivery2.exchange
                      ,&amp;delivery2.routing_key
                      ,&amp;delivery2.redelivered
                      ,&amp;delivery2.properties
                      ,&amp;s
                  );
                  slog::info!(my_slog_logger,&quot;{}&quot;,log_message);
                  std::thread::sleep(std::time::Duration::from_millis(sleep_duration_ms));
                  slog::info!(my_slog_logger,&quot;After {}ms sleep.&quot;,sleep_duration_ms);
                  channel2
                      .basic_ack(delivery2.delivery_tag, BasicAckOptions::default())
                      .await
                      .expect(&quot;ack&quot;)
                  ;
              }
              Ok(message_cnt)
          }
      );
      res
  }
  </code></pre>