2016-11-06 2 views
0

folgenden Code-Schnipsel vor:Wrapping Funktionsaufruf in Task.async verursacht seltsames Verhalten, das ich nicht verstehe

a)

IO.puts "test1" 
task = Task.async fn -> 
    Foo.Bar.send_file_for_processing(file_url) 
end 
IO.puts "test2" 
content = Task.await(task) 
IO.puts "test4" 

b)

IO.puts "test1" 
content = Foo.Bar.send_file_for_processing(file_url) 
IO.puts "test2" 

und in Foo. Stabmodul:

def send_file_for_processing(file_url) do 
    json = file_url |> encoded_file |> request_json 
    IO.puts "test3" 
    request = HTTPoison.post(
    @processing_endpoint, 
    json, 
    @headers, 
    params: %{"key": @api_key}, connect_timeout: 100000, recv_timeout: 100000, timeout: 100000 
) 
    IO.puts "test5" 

    (...) 
end 

Wh de Ich benutze Code-Snippet a), der "test5" wird nie erreicht, als würde das Programm während der HTTPoison-POST-Anfrage hängen bleiben. Es endet nie. In der Zwischenzeit wird mit dem Snippet b) die HTTPoison-POST-Anforderung normal und ohne Verzögerungen abgeschlossen.

Um ehrlich zu sein, hat mich das Debuggen dazu gebracht etwas Zeit zu verlieren und ich verstehe das Problem mit dem Snippet a) immer noch nicht. Missbrauche ich das Task-Modul? Ich habe die Dokumentation überprüft und konnte nichts finden, was dieses Problem erklären würde.

EDIT: Ausgang für Schnipsel a)

test1 
test2 
test3 
+0

Sie haben 2 '" test3 "' Debug-Ausgabe, würde es Ihnen etwas ausmachen, eine von ihnen zu ändern und zu bestätigen, dass die Aufgabe eine Zeile _before_ HTTPoison Anfrage druckt? – mudasobwa

+0

@mudasobwa done –

+0

@ PawełDuda können Sie versuchen, ein minimales reproduzierbares Beispiel zu erstellen, das dieses Verhalten zeigt? – Dogbert

Antwort

1

Ich kann sehen Sie hohe Timeout-Werte für die HTTP-Anforderung haben. Die Task hat einen Standardzeitüberschreitungswert von 5_000 ms, daher ist es sehr gut möglich, dass die Tasktimeouts vor der Anforderung beendet werden. Anschließend wird die Aufgabe abgebrochen und Sie sehen nie die Ausgabe. Die Funktion Task.await/2 akzeptiert das Timeout als zweites Argument.

Unabhängig davon sollten Sie eine Task Timeout Fehler sehen. Vielleicht ignorierst du etwas Ausgabe?

+0

Ich wünschte wirklich, dass es hier der Fall war, aber die Aufgabe scheint nicht das Zeitlimit zu sein ... Selbst wenn etwas länger als 5 Sekunden dauert, endet es schließlich richtig. Außerdem sollte das Programm im Falle einer Zeitüberschreitung über 'Task.await' hinausgehen und" test4 "drucken, was nicht geschieht:/ –

+0

Beide Dinge sind nicht wahr. Nach Ablauf der Zeitüberschreitung wird die Task beendet und der Task-Prozess wird sofort beendet. Da der Aufrufer von "Task.async/1" mit der Aufgabe verknüpft ist, wird der Prozess ebenfalls beendet, wenn die Aufgabe in "Task.await/2" abläuft. Daher sollte "test4" niemals erscheinen. – michalmuskala

+0

Sie hatten Recht. Ich habe das Timeout auf '100_000' erhöht und nun scheint es sich korrekt zu verhalten :) Danke, ich hätte sicherlich viel mehr Zeit damit verbracht, dies zu verfolgen. –

Verwandte Themen