it's easy to have "nested" futures in rust, where one top-level future (our control thread) owns its subcomponents (like a protocol component, scheduler component, and so on), and the `poll` method for the top-level future then `poll`s all of its subcomponents. in this case we manually write our own `poll` implementations, but it's also easy to express these patterns with combinators like `FuturesUnordered`.
then, we have really good cancellation properties in our system. if we decide to cancel a file, we just drop its future, and we can be sure that all of the resources held by its "subtree" of futures will be released.
I'd be curious to hear your take on the "structured concurrency in Rust" conversation here https://trio.discourse.group/t/structured-concurrency-in-rus...
in my understanding, the pure futures approach in rust goes even further than the nursery approach in trio, where there isn't even a "local" notion of forking off a task in the background. if a future wants to do an operation in the background, it's responsible for `join`ing on it itself or finding some other way to ensure it gets `poll`ed. this setup is a good fit for rust since the parent future maintains ownership over its child, and dropping the parent future immediately cancels the background tasks.
but, for what it's worth, I think there's lots of tradeoffs in this space, and we have yet to find really good patterns for structuring async code. so it's good to see so much experimentation.