jhelovuo / RustDDS

Rust implementation of Data Distribution Service

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

busy looping on DataReader.take()

mango009 opened this issue · comments

Sorry I'm new on Rust and this library so just want to understand if I'm using it properly. Below is my code snippet of creating a DataReader to take form a topic:

fn adn_status_reader() {
  let topic_name = String::from("ads status");
  let type_desc = String::from("ads status message");
  let domain_id = 0;
  let qos = QosPolicyBuilder::new().build();
  let participant = DomainParticipant::new(domain_id).unwrap();
  let topic = participant.create_topic(topic_name, type_desc, &qos, TopicKind::NoKey).unwrap();
  let subscriber = participant.create_subscriber(&qos).unwrap();
  let mut datareader = subscriber.create_datareader_no_key::<AdsStatusMsg, CDRDeserializerAdapter<_>>(&topic, None).unwrap();

  for i in 0..1000 {
    log(&format!("Waiting: {:?}", i));
    let messages = match datareader.take(10, rustdds::ReadCondition::not_read()) {
      Ok(messages) => {
        log(&format!("message len: {:?}", messages.len()));
        messages
      },
      Err(e) => {
        log(&format!("Error: {:?}", e));
        continue;
      }
    };

    for sample in &messages {
      log(&format!("Received: {:?}", sample));
    }
  }
}

When I ran the program (no data on the topic yet), datareader.take simply just return with no error and 0 length vector. And the function return immediately with the following output:

2023-07-21 11:40:26.228928129 -07:00: Waiting: 0
2023-07-21 11:40:26.229053619 -07:00: message len: 0
2023-07-21 11:40:26.229066068 -07:00: Waiting: 1
2023-07-21 11:40:26.229075584 -07:00: message len: 0
2023-07-21 11:40:26.229080668 -07:00: Waiting: 2
2023-07-21 11:40:26.229096725 -07:00: message len: 0
2023-07-21 11:40:26.229101720 -07:00: Waiting: 3
2023-07-21 11:40:26.229116647 -07:00: message len: 0
2023-07-21 11:40:26.229127537 -07:00: Waiting: 4
2023-07-21 11:40:26.229136371 -07:00: message len: 0
2023-07-21 11:40:26.229148407 -07:00: Waiting: 5
2023-07-21 11:40:26.229157642 -07:00: message len: 0
2023-07-21 11:40:26.229169613 -07:00: Waiting: 6
2023-07-21 11:40:26.229177412 -07:00: message len: 0
2023-07-21 11:40:26.229188980 -07:00: Waiting: 7
....

Apparently I'm missing something to use the library properly. Any help?

Hi. datareader.take(10, rustdds::ReadCondition::not_read()) takes at most 10 messages that haven't been read. Therefore if there are 0 messages, it will return all of the 0 messages. You should probably wait until data becomes available and then take. If you are just trying to hack something together you could maybe try taking once per second, or you could have a look at the examples such as shapes demo.

Thanks for the reply, how do I wait for data become available? As I don't see there's no such methods in DataReader or Subscriber.

Yes, there are no direct methods to wait, but DataReader implements interfaces to wait for incoming data. You can use either the mio package, either version 0.6 or 0.8, or use async programming and call async_sample_stream.

Thanks. I looked at the traits DataReader implements but it was not obvious to me which interface that allows for waiting for incoming data?

Thanks for any clarification

async_sample_stream gives you a stream, which is basically an asynchronous iterator. It can be called multiple times to get a future of the next element in the stream, and awaiting the future makes that part of the program wait for the incoming data. See the (section on streams in the) async rust book, and you can take a look at the async_shapes_demo when you have gotten up to speed on asynchronous rust.

Thank you. I'll look into async of Rust. At first I was just toying with this library and wanted to come up with some 'hello world' program. I think the fact that DataReader.take(&mut self, max_sample, read_condition) is not very useful if it returns even there's nothing available. I think a more reasonable behavior is that it should block if there's no data.