[Solved] Long-running maintainence threads in a struct


#1

Hello all,

I’m currently working on a safe and fast autonomous ground control station for unmanned vehicles in Rust and I’ve come across a problem when trying to implement a thread that attempts to persistently maintain a communications link.


pub struct Vehicle {
....
}

impl Vehicle {
   ...

   /// many omissions in this method to keep it short here
   pub fn start_keepalive_connection(&'static mut self) {
        thread::spawn(move || {
            loop {
              self.try_start_connection();
            }
        });

    }
   ...
}

The behavior I want is that the caller can start this keepalive connection and this thread constantly tries to maintain a connection with the vehicle. However - I can only get it to compile when 'static lifetimes are used, as expected, and new Vehicle structs will get initialized over the lifetime of the program - a.k.a not known in advance - so this doesn’t work.

My question is: is there any way that threads can be scoped to the lifetime of the struct? My beginner intuition is that I could kill the thread by implementing Drop manually to satisfy the compiler, but I’m unsure if Rust supports such behavior.

Thanks!


#2

If I understand correctly, you want to be able to interact with the Vehicle connection in another thread while this thread “just” maintains the connection? If yes, you would at least need to have the vehicle, or the part of it that handles the connection, wrapped in a Arc<Mutex<...>> so that the two threads don’t simultaneously manipulate the socket/device file/whatever you are communicating over.

But a much more flexible and idiomatic way would be to handle all communications in the thread, and use channels to send commands to/receive replies from it. That way, the only thing shared is the channel connection, which is managed completely by Rust. A special message can signal the thread to close the connection.


#3

Thanks for your reply, @birkenfeld - the suggestion that I should be doing send/receive operations on this thread through channels is definitely something I’ll do now.

My main concern is - how do I run this maintaining thread only for the lifetime of this struct, since it’s not present for the entire lifetime of the program (aka self is not static)? I had to annotate the type as static for the program to compile, but when I attempt to use the method, as expected, I cannot call it unless the Vehicle itself is present for the static lifetime.


#4

The idea is that the thread does not have access to the struct, only to its end of the channels.

As I said, if you want to share data between threads, you’ll have to go through Arc (and Mutex for mutability) - which will keep the contents alive until all threads using them release it.


#5

Ok, thanks! I’ll try implementing it in that manner.