Skip to content

Dropping a Subscriber hangs, leaking a thread and a socket to the publishing nodes #218

@DomWilliamsEE

Description

@DomWilliamsEE

When a Subscriber drops, its thread (spawned in join_connection) hangs forever on reading from the socket, which prevents the thread or socket from being shutdown. This holds open the tcp socket in the publishing nodes, and in practice leads to exhausting all the file descriptors.

Small reproducing case:

fn main() {
    rosrust::init("testing");

    spawn(|| {
        let mut sub = None;
        loop {
            match sub {
                None => {
                    sub = Some(
                        rosrust::subscribe("/topic", 10, |msg: rosrust_msg::std_msgs::String| {})
                            .unwrap(),
                    );
                }
                Some(_instance) => {
                    println!("dropped");

                    sub = None;
                }
            }

            sleep(Duration::from_secs(1));
        }
    });

    rosrust::spin();
}

This flip flops between subscribing and unsubscribing every second. Having another node that just publishes to this topic will steadily grow in the number of sockets it has open (visible in /proc/$pid/fd), while the rust node spawns more and more threads.

I have done a quick fix which is probably not ideal, which 1) sets an atomic bool when the subscriber has been dropped and the threads+sockets should be cleaned up, and 2) sets a slow timeout on a recv() so it has a chance to check this atomic bool. I'll open a PR for it anyway.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions