Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apparent memory leak in Discovery Server Listener #213

Open
KeaneWong opened this issue Feb 27, 2025 · 0 comments
Open

Apparent memory leak in Discovery Server Listener #213

KeaneWong opened this issue Feb 27, 2025 · 0 comments

Comments

@KeaneWong
Copy link

KeaneWong commented Feb 27, 2025

Hello, I am setting up a Discovery Server to connect a pair of clients (both local, in the same program) sending Request-Reply data to one another for a proof of concept.
While setting up the server and binding a listener, I encountered the following message:

swig/python detected a memory leak of type 'eprosima::fastdds::rtps::ParticipantDiscoveryStatus *', no destructor found.
swig/python detected a memory leak of type 'eprosima::fastdds::rtps::ReaderDiscoveryStatus *', no destructor found.

The same occurs if the participant was a DataWriter.

It kinda looks like when a participant is discovered, the callback on_participant_discovery is are called with Enums of type ParticipantDiscoverStatus, which isn't destroyed correctly. Is it possible the ParticipantDiscoveryStatus type might not be recognized by Swig and so no destructor is created for it?

Or if I'm setting up the server incorrectly, would I be able to get some guidance on the better way to do it? I have been attempting to set up based off the C++ examples in the documentation
Any help would be greatly appreciated.

The minimal reproducing example is below

#!/usr/bin/env python3

import fastdds
from fastdds import (
    DiscoveryProtocol_SERVER,
    DiscoveryProtocol_CLIENT,

)

# Path to the python binding files
from FastDDS_API.hwbuild.HelloWorld import (
    HelloWorld,
    HelloWorldPubSubType
)


class ReaderListener(fastdds.DataReaderListener):
    def __init__(self):
        super().__init__()

    def on_data_available(self, reader):
        info = fastdds.SampleInfo()
        data = HelloWorld()
        reader.take_next_sample(data, info)
        message = data.message()
        print("Message was", message)

    def on_subscription_matched(self, datareader, info):
        if 0 < info.current_count_change:
            print(
                "Subscriber matched publisher {}".format(
                    info.last_publication_handle
                )
            )
        else:
            print(
                "Subscriber unmatched publisher {}".format(
                    info.last_publication_handle
                )
            )


class Reader:
    def __init__(self, domain):
        # Initialize factory qos
        factory = fastdds.DomainParticipantFactory.get_instance()
        self.participant_qos = fastdds.DomainParticipantQos()
        (self.participant_qos.wire_protocol()
         .builtin.discovery_config).discoveryProtocol = DiscoveryProtocol_CLIENT

        # Locator configuration
        server_locator = fastdds.Locator_t()
        server_locator.kind = fastdds.LOCATOR_KIND_UDPv6
        server_locator.port = 5000
        server_locator.address = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)
        (self.participant_qos.wire_protocol().builtin.discovery_config
         .m_DiscoveryServers.push_back(server_locator))

        factory.get_default_participant_qos(self.participant_qos)
        self.participant = factory.create_participant(
            domain, self.participant_qos
        )

        self.topic_data_type = HelloWorldPubSubType()
        self.topic_data_type.set_name("HelloWorld")
        self.type_support = fastdds.TypeSupport(self.topic_data_type)
        self.participant.register_type(self.type_support)

        self.topic_qos = fastdds.TopicQos()
        self.participant.get_default_topic_qos(self.topic_qos)
        self.topic = self.participant.create_topic(
            "HelloWorldTopic",
            self.topic_data_type.get_name(),
            self.topic_qos,
        )

        self.subscriber_qos = fastdds.SubscriberQos()
        self.participant.get_default_subscriber_qos(self.subscriber_qos)
        self.subscriber = self.participant.create_subscriber(
            self.subscriber_qos
        )

        self.listener = ReaderListener()
        self.reader_qos = fastdds.DataReaderQos()
        self.subscriber.get_default_datareader_qos(self.reader_qos)
        self.reader = self.subscriber.create_datareader(
            self.topic, self.reader_qos, self.listener
        )

    def __del__(self):
        factory = fastdds.DomainParticipantFactory.get_instance()
        self.participant.delete_contained_entities()
        factory.delete_participant(self.participant)


class ServerListener(fastdds.DomainParticipantListener):
    def __init__(self):
        super().__init__()

    def on_participant_discovery(self, participant, reason, info, should_be_ignored):
        print("Participant discovered")


class Server:
    def __init__(self, domain):

        # Initialize factory_qos
        factory = fastdds.DomainParticipantFactory.get_instance()
        self.participant_qos = fastdds.DomainParticipantQos()
        self.participant_qos.name("DS-Server")
        (self.participant_qos.wire_protocol()
         .builtin.discovery_config).discoveryProtocol = DiscoveryProtocol_SERVER

        # Locator configuration
        listening_locator = fastdds.Locator_t()
        listening_locator.kind = fastdds.LOCATOR_KIND_UDPv6
        listening_locator.port = 5000
        listening_locator.address = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)
        (self.participant_qos.wire_protocol()
         .builtin.metatrafficUnicastLocatorList.push_back(listening_locator))
        (self.participant_qos.wire_protocol()
         .builtin.discovery_config.m_DiscoveryServers.push_back(listening_locator))
        # Uncomment to filter other hosts
        (
            self.participant_qos.wire_protocol().builtin.discovery_config
        ).ignoreParticipantFlags = fastdds.FILTER_DIFFERENT_HOST

        factory.get_default_participant_qos(self.participant_qos)

        self.listener = ServerListener()

        self.participant = factory.create_participant(
            domain, self.participant_qos, self.listener
        )
        if not self.participant:
            raise Exception("No server participant created")

    def __del__(self):
        factory = fastdds.DomainParticipantFactory.get_instance()
        self.participant.delete_contained_entities()
        factory.delete_participant(self.participant)

    def run(self):
        try:
            input('Press any key to stop\n')
        except Exception as _:
            pass


fastdds_server = Server(0)
fastdds_reader = Reader(0)
fastdds_server.run()
exit(0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant