Reputation: 1586
Assume we make an HTTP request from a dart:io application using the http package with a timeout configured:
dynamic getSomething(String url) async {
try {
var response = await http.get(url).timeout(new Duration(seconds: 30));
return JSON.decode(response.body);
} catch (_) {
return null;
}
}
There are two futures here, one generated by http.get (the request Future) and the other generated by Future.timeout (the timeout Future). Should the request Future complete, its value is delivered to the timeout Future which is in turn completed. That's good.
However, if the http.get does not complete in 30 seconds, the timeout future will complete and throw a TimeoutException. What happens to the request Future? There is certainly some state and memory allocation associated with the request Future that isn't specifically cleaned up by just running the timeout Future. Worse yet, if the request Future does complete after the timeout, that code will still execute. Is it the responsibility of the timeout Future to specifically cancel the request - which in this case, is not possible because it is buried in package - or is there some other mechanism that must be used?
More generally, does a Future that doesn't ever complete eventually get its state and memory cleaned up, or does it hang around forever?
Upvotes: 2
Views: 620
Reputation: 340
A Future will get garbage collected when there are no references to it, just like any other variable. There's nothing inherently different about Future variables. For example, they are not an operating system construct.
In your http example, the timeout Future is chained from the original Future, so if the original Future completes, then the timeout Future will complete too. In the opposite case, where the timeout triggers, the http operation will hold a reference to the original future (which holds a reference to the timeout future) until the http operation completes. So the only way that the Futures might leak is if the http request never returned, but at that point you are leaking http connections and you have bigger problems than leaking a couple of Futures.
Note that the fact that the timeout Future completes doesn't mean there's an error. Errors behave differently. An error would cause the Future to either call catchError() or to call your callback.
Upvotes: 3