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.