Skip to content

Reader stops reading after writer restarts #32

Description

@Davide-1998

Hi, I tried to run a simple reader-writer setup with zero-dds and find out that if a writer dies and is restarted, the reader stops reading the new samples.
Following are the code snippets that I used:

Robot.idl

struct Robot {
    uint32 id;
    uint32 label;
};

build.rs

fn main() {
    zerodds_build::Config::new().out_dir("./generated").compile(&["./idl/Robot.idl"]).unwrap();
}

reader.rs

use zerodds_dcps::{
    DataReaderQos, DomainParticipantFactory, DomainParticipantQos, SubscriberQos, TopicQos,
};
#[allow(clippy::all, clippy::pedantic, dead_code)]
mod generated {
    include!("../generated/Robot.rs");
}

use generated::Robot;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let factory = DomainParticipantFactory::instance();

    let participant = factory
        .create_participant(100, DomainParticipantQos::default())
        .unwrap();
    let robot_topic = participant
        .create_topic::<Robot>("robot", TopicQos::default())
        .expect("create_topic");

    let subscriber = participant.create_subscriber(SubscriberQos::default());
    let reader = subscriber
        .create_datareader::<Robot>(&robot_topic, DataReaderQos::default())
        .expect("create_datawriter");

    println!("Waiting");
    reader
        .wait_for_matched_publication(1, core::time::Duration::from_secs(10))
        .unwrap();
    println!("Found one reader");

    let mut count: u64 = 0;
    loop {
        reader
            .wait_for_data(core::time::Duration::from_secs(10))
            .unwrap();
        match reader.take() {
            Ok(samples) if !samples.is_empty() => {
                for item in samples {
                    println!("Read #{count}: id {} | label '{}'", item.id, item.label);
                    count += 1;
                }
            }

            Ok(_) => {
                unreachable!()
            }

            Err(err) => {
                println!("error: {}", err)
            }
        }
    }
}

writer.rs

use std::{thread::sleep, time::Duration};

use zerodds_dcps::{
    DataWriterQos, DomainParticipantFactory, DomainParticipantQos, PublisherQos, TopicQos,
};

#[allow(clippy::all, clippy::pedantic, dead_code)]
mod generated {
    include!("generated/Robot.rs");
}

use generated::Robot;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let factory = DomainParticipantFactory::instance();

    let participant = factory
        .create_participant(100, DomainParticipantQos::default())
        .unwrap();
    let robot_topic = participant
        .create_topic::<Robot>("robot", TopicQos::default())
        .expect("create_topic");

    let publisher = participant.create_publisher(PublisherQos::default());
    let writer = publisher
        .create_datawriter::<Robot>(&robot_topic, DataWriterQos::default())
        .expect("create_datawriter");

    let mut count: u32 = 0;
    loop {
        let sample = Robot {
            id: count,
            label: count,
        };
        writer.write(&sample).expect("write");
        println!("Written Robot: id {} | label {}", sample.id, sample.label);
        count += 1;
        sleep(Duration::from_millis(500));
    }
}

Observed Output

// Reader
Waiting
Found one reader
Read #0: id 1 | label '1'
Read #1: id 2 | label '2'
Read #2: id 3 | label '3'

// Here writer dies
// Writer
Written Robot: id 1 | label 1
Written Robot: id 2 | label 2
Written Robot: id 3 | label 3

// writer dies

// writer restarts

Written Robot: id 1 | label 1
Written Robot: id 2 | label 2
Written Robot: id 3 | label 3

Expected Output

// Reader
Waiting
Found one reader
Read #0: id 1 | label '1'
Read #1: id 2 | label '2'
Read #2: id 3 | label '3'

// Here writer dies
// Writer restarts

Read #3: id 1 | label '1'
Read #4: id 2 | label '2'
Read #5: id 3 | label '3'

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions