2016-11-06 2 views
0

Рассмотрим следующие фрагменты кода:Обертывание в Task.async вызывает странное поведение, что я не понимаю

)

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" 

б)

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

и в Foo. Барный модуль:

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 ru Я использую фрагмент кода a), «test5» никогда не был достигнут, как если бы программа зависала во время запроса HTTPOison POST. Он просто не заканчивается. Между тем, со сниппетом b), HTTPoison POST-запрос завершается нормально и без каких-либо задержек.

Если честно, отладка этого заставила меня потерять некоторое время, и я до сих пор не понимаю проблему со сниппетом а). Я неправильно использую модуль Task? Я проверил документацию и не нашел ничего, что могло бы объяснить мне эту проблему.

EDIT: Выход для сниппета а)

test1 
test2 
test3 
+0

У вас есть 2 '' test3 '' отладочный вывод, не могли бы вы изменить любой из них и подтвердить, что задача заключается в печати строки _before_ HTTPoison request? – mudasobwa

+0

@mudasobwa done –

+0

@ PawełDuda вы можете попытаться создать минимальный воспроизводимый пример, демонстрирующий это поведение? – Dogbert

ответ

1

Я вижу, что высокие значения тайм-аута для запроса HTTP. Задача имеет значение тайм-аута по умолчанию 5_000 ms, поэтому очень вероятно, что таймауты задачи перед запросом будут завершены. Впоследствии задача убита, и вы никогда не увидите результат. Функция Task.await/2 принимает таймаут в качестве второго аргумента.

Независимо от того, что вы должны видеть ошибки таймаута задачи. Возможно, вы игнорируете некоторые результаты?

+0

Мне очень жаль, что это было здесь, но задача, похоже, не в том, чтобы выходить из строя ... Даже если что-то занимает больше 5 секунд, оно в конечном итоге заканчивается должным образом. Кроме того, в случае тайм-аута программа должна продолжить «Task.await» и распечатать «test4», которой не бывает:/ –

+0

Обе эти вещи неверны. По истечении таймаута задача уничтожается, и процесс задачи немедленно завершается. Кроме того, поскольку вызывающий объект «Task.async/1» связан с задачей, когда задача выполняется в «Task.await/2», процесс также умирает, поэтому «test4» никогда не должен появляться. – michalmuskala

+0

Вы были правы. Я увеличил тайм-аут до '100_000', и теперь он выглядит корректно :) Спасибо, я бы наверняка потратил намного больше времени на отслеживание этого. –

Смежные вопросы