2016-04-11 11 views
1

Angenommen wir eine HTTP-Anforderung von einem Dart machen: io-Anwendung mit dem http-Paket mit einem Timeout konfiguriert:Wie bereinigt Dart: io Futures, die Timeout?

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; 
    } 
} 

Es gibt zwei Futures hier, eine, die durch http.get (Antrag Zukunft) und die anderen generiert von Future.timeout (das Timeout Future). Sollte die Anfrage Future abgeschlossen sein, wird der Wert an das Timeout Future geliefert, welches wiederum abgeschlossen ist. Das ist gut.

Wenn jedoch http.get nicht innerhalb von 30 Sekunden abgeschlossen wird, wird die Zeitüberschreitung abgeschlossen und eine TimeoutException ausgelöst. Was passiert mit der Anfrage Zukunft? Es gibt sicherlich einige Status- und Speicherzuweisungen, die mit der Anfrage Zukunft verknüpft sind, die nicht speziell bereinigt wird, indem einfach das Timeout-Future ausgeführt wird. Schlimmer noch, Wenn die Anfrage Future nach dem Timeout abgeschlossen wird, wird dieser Code weiterhin ausgeführt. Ist es die Verantwortung des Timeout-Futures, die Anfrage speziell zu stornieren - was in diesem Fall nicht möglich ist, weil es im Paket vergraben ist - oder gibt es einen anderen Mechanismus, der verwendet werden muss?

Allgemeiner, wird eine Zukunft, die niemals abgeschlossen wird, irgendwann ihren Zustand und Speicher bereinigt oder bleibt sie für immer hängen?

+0

Es scheint, als würde keine Bereinigung stattfinden. Ich denke, der Timeout-Callback müsste sich darum kümmern. Es gibt ein verwandtes Problem für "HttpRequest" https://github.com/dart-lang/http/issues/21 –

Antwort

1

Eine Zukunft wird Müll gesammelt, wenn es keine Referenzen darauf gibt, genau wie jede andere Variable. Future-Variablen unterscheiden sich nicht von Natur aus. Zum Beispiel sind sie kein Betriebssystemkonstrukt.

In Ihrem http-Beispiel ist die Zeitüberschreitung Future aus der ursprünglichen Zukunft verkettet, wenn also die ursprüngliche Zukunft abgeschlossen ist, wird auch die Zeitüberschreitung Future abgeschlossen. Im gegenteiligen Fall, in dem das Zeitlimit ausgelöst wird, enthält die http-Operation einen Verweis auf die ursprüngliche Zukunft (die einen Verweis auf die Zeitüberschreitung enthält), bis die http-Operation abgeschlossen ist. Die einzige Möglichkeit, dass die Futures auslaufen, ist, dass die http-Anfrage nie zurückgegeben wird, aber zu diesem Zeitpunkt gibt es HTTP-Verbindungen und Sie haben größere Probleme, als ein paar Futures zu verlieren.

Beachten Sie, dass die Tatsache, dass das Timeout Future abgeschlossen wird, nicht bedeutet, dass ein Fehler vorliegt. Fehler verhalten sich anders. Ein Fehler würde dazu führen, dass die Future entweder catchError() aufruft oder Ihren Callback aufruft.