Skip to content

find_topic returning incorrect TopicKind #377

@sevnx

Description

@sevnx

Summary

The Topic element returned by the find_topic method in the DataParticipant incorrectly reports the TopicKind.

Reproducible example

use rustdds::{DomainParticipant, Keyed, QosPolicies};
use serde::{Deserialize, Serialize};
use std::time::Duration;

#[derive(Serialize, Deserialize, Clone, Debug)]
struct HelloWorldData {
    pub user_id: i32,
    pub message: String,
}

impl Keyed for HelloWorldData {
    type K = i32;

    fn key(&self) -> Self::K {
        self.user_id
    }
}

fn main() {
    let dp = DomainParticipant::new(0).expect("Failed to create DomainParticipant");

    let topic = dp
        .create_topic(
            "HelloWorld".to_owned(),
            "HelloWorldData".to_owned(),
            &QosPolicies::qos_none(),
            rustdds::TopicKind::WithKey,
        )
        .unwrap();

    let publisher = dp.create_publisher(&QosPolicies::qos_none()).unwrap();

    publisher
        .create_datawriter_cdr::<HelloWorldData>(&topic, None)
        .unwrap();

    let found_topic = dp
        .find_topic("HelloWorld", Duration::from_secs(1))
        .unwrap()
        .unwrap();

    assert_eq!(topic.kind(), found_topic.kind());
}

This example currently panics

thread 'main' panicked at src/main.rs:45:5:
assertion `left == right` failed
  left: WithKey
 right: NoKey

Analysis

The problem stems from the find_topic_in_discovery_db method in src/dds/particpant.rs:1330

let build_topic_fn = |d: &DiscoveredTopicData| {
      let qos = d.topic_data.qos();
      let topic_kind = match d.topic_data.key {
        Some(_) => TopicKind::WithKey,
        None => TopicKind::NoKey,
      };
      let name = d.topic_name().clone();
      let type_desc = d.topic_data.type_name.clone();
      self.create_topic(domain_participant_weak, name, type_desc, &qos, topic_kind)
    };

Here the decision whether the topic is keyed is done based on the key field of the DiscoveredTopicData, however that seems to be incorrect as I couldn't find a place in the specification where it would be interpreted as such. What's more, implementation of to_topic_data for pub/sub always set it to None.

I also checked why the Topic needs the information about being Keyed or not, and it is only used for checks when creating a DataReader, to not be able to create a Keyed DataReader for a NonKeyed Topic. (those checks are not present for DataWriter).

Proposed solution

A possible solution would be to find another way to identify if a Topic is keyed or not, would you have an idea on how to do so ?

Other than that, shouldn't a similar check (Keyed / NonKeyed w/ Topic) be added to the DataWriter?

Metadata

Metadata

Assignees

Labels

questionFurther information is requested

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions