Hone logo
Hone
Problems

Deferred Deletion in Rust: Implementing a Delayed Cleanup Mechanism

Many applications require resources to be cleaned up only after a certain period or after all operations involving them have concluded. This is often referred to as "deferred deletion." In Rust, a language that emphasizes memory safety and explicit resource management, implementing such a mechanism efficiently and safely requires careful consideration of ownership, lifetimes, and concurrency.

Problem Description

Your task is to design and implement a mechanism in Rust that allows for the deferred deletion of resources. This mechanism should:

  1. Schedule Deletion: Allow a resource to be marked for deletion, but the actual deallocation should only happen after a specified delay or after a certain number of "acknowledgements" have been received.
  2. Handle Concurrent Access: The mechanism must be thread-safe, as multiple threads might be accessing and potentially scheduling the deletion of the same resource.
  3. Prevent Premature Deletion: Ensure that a resource is not deleted if it's still actively being used or if its scheduled deletion has been cancelled.
  4. Resource Representation: For this challenge, a resource can be represented by a simple integer u32. The "deletion" will involve printing a message indicating the resource has been cleaned up.

Key Requirements:

  • A central manager (e.g., a struct) that orchestrates the deferred deletion.
  • A way to register resources with the manager.
  • A way to schedule a resource for deletion after a specified delay (in milliseconds).
  • A way to "cancel" a scheduled deletion before it occurs.
  • A mechanism to ensure the manager itself lives long enough to perform its cleanup tasks.

Expected Behavior:

When a resource is scheduled for deletion with a delay:

  • If no cancellation occurs within the delay, a "Resource [ID] cleaned up" message should be printed.
  • If the deletion is cancelled before the delay expires, no cleanup message should be printed for that specific deletion event.

Edge Cases:

  • Scheduling deletion for a resource that has already been deleted.
  • Cancelling a deletion that has already occurred or was never scheduled.
  • Multiple scheduled deletions for the same resource.

Examples

Example 1:

// In a main thread or a separate manager thread

// Schedule resource 1 for deletion after 100ms
// Schedule resource 2 for deletion after 200ms

// After 150ms, cancel deletion for resource 1

// After 300ms, observe the output

Output:

Resource 2 cleaned up

Explanation: Resource 1's deletion was scheduled but then cancelled before the 100ms delay. Resource 2's deletion was scheduled for 200ms and occurred as planned.

Example 2:

// In a main thread or a separate manager thread

// Schedule resource 3 for deletion after 50ms
// Schedule resource 3 for deletion again after 150ms (effectively replacing the first schedule)

// After 100ms, cancel deletion for resource 3

// After 200ms, observe the output

Output:

(No output related to resource 3)

Explanation: The second scheduling of resource 3 overwrites the first. The cancellation then removes the pending deletion for resource 3 before the 150ms delay expires.

Example 3:

// In a main thread or a separate manager thread

// Schedule resource 4 for deletion after 50ms
// After 60ms, attempt to cancel deletion for resource 4

Output:

Resource 4 cleaned up

Explanation: The deletion for resource 4 occurred before the cancellation request could be processed effectively by the manager.

Constraints

  • The maximum number of unique resources to manage at any given time is 1000.
  • The maximum delay for deletion is 5000 milliseconds (5 seconds).
  • The manager should be able to handle up to 100 concurrent requests to schedule or cancel deletions.
  • The cleanup operations themselves are considered instantaneous for the purpose of this challenge.

Notes

  • Consider using std::sync::{Mutex, Arc} for thread-safe sharing of the manager's state.
  • The std::thread::sleep function can be useful for simulating delays, but for a more robust solution in a real-world scenario, you might consider asynchronous runtimes like tokio or async-std and their scheduling capabilities.
  • You'll need a way to keep track of scheduled deletions, perhaps using a HashMap where the key is the resource ID and the value is some identifier for the pending task that can be cancelled.
  • Think about how to manage the lifetime of the threads or background tasks responsible for performing the actual cleanup. A common pattern is to have a "shutdown" signal.
Loading editor...
rust