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

No fields configured for Bug.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions