Setting Up
Before writing any cleanup logic, let's get a project in place. If you'd rather skip ahead and
just read finished code, the showcase/ crate in the redrop repository is exactly what we build
over the next few chapters — feel free to open it side by side.
Add the dependency
In your Cargo.toml:
[dependencies]
redrop = { version = "0.1", features = ["tokio"] }
That tokio feature is optional, and worth pausing on:
- Without it, redrop is runtime-agnostic. Cleanup work just queues up until you explicitly
.awaita function calledredrop::shutdown(), on whatever executor you're using. - With it, redrop additionally starts a small background task (once it's able to — the first time it gets a chance to run inside a live Tokio runtime) that continuously works through queued cleanup as it arrives, instead of only when you ask it to.
We'll use the tokio feature for this tutorial, since it's the more common setup and it lets us
see cleanup happening in the background as we go. Chapter 4 comes back to explain the difference
in more depth.
A shape to hang the example on
We're going to build a small LogShipper: something that buffers a few log lines and needs to
flush them over the network before it's really done. It doesn't matter that the "network" part
is faked with a tokio::time::sleep in our example — the shape is the same as a real one.
#[derive(Default)]
struct LogShipper {
id: usize,
buffered_lines: usize,
}
Notice the #[derive(Default)]. Keep that in mind — we'll explain exactly why it's required
in the next chapter, once you've seen what the macro generates.
That's all the setup we need. On to the interesting part.