Is this safe or idiomatic for cleanup in Drop?

⚓ Rust    📅 2025-04-29    👤 surdeus    👁️ 4      

surdeus

Warning

This post was published 114 days ago. The information described in this article may have changed.

TL;DR

I'm seeking feedback on the following design pattern for automatically tearing down preset data during unit testing. I'm not sure whether this approach is considered bad practice in the context of Rust testing.

Details

I've looked into various resources and considered the trade-offs. My main motivation is to make the test variable self-responsible for its own cleanup, rather than relying on the user to remember to explicitly call a cleanup method.

I came across this closure-style solution, which does achieve the goal, but I find it a bit verbose in practice.

Therefore, I'm hoping to gather insights or suggestions from more experienced Rust developers. Is there a cleaner or more idiomatic way to approach this? Or is the strategy of embedding async teardown logic in Drop inherently flawed?

Thanks in advance!

use std::{
    sync::{Arc, atomic::{AtomicBool, Ordering}},
    thread::sleep,
    time::Duration,
};

impl Drop for SeedingStruct {
    fn drop(&mut self) {
        let is_done = Arc::new(AtomicBool::new(false));
        let is_done_clone = Arc::clone(&is_done);
        let cloned_self = self.clone();

        let task = async move {
            Resource::delete_by_id(None, cloned_self.resource_id)
                .await
                .expect("Failed to delete resource by its ID");
            is_done_clone.store(true, Ordering::SeqCst);
        };

        // Spawn async task
        let _ = tokio::spawn(task);

        // Busy-wait until the task completes
        while !is_done.load(Ordering::SeqCst) {
            sleep(Duration::from_millis(1));
        }
    }
}

3 posts - 2 participants

Read full topic

🏷️ rust_feed