【问题标题】:Wrapping function call in Task.async causes weird behaviour that I do not understand在 Task.async 中包装函数调用会导致我不理解的奇怪行为
【发布时间】:2016-11-06 13:50:15
【问题描述】:

考虑下面的sn-ps代码:

一)

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"

在 Foo.Bar 模块中:

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

当我使用代码 sn-p a) 时,永远不会到达“test5”,就好像程序会在 HTTPoison POST 请求期间挂起一样。它只是永远不会结束。同时,使用 sn-p b),HTTPoison POST 请求正常完成,没有任何延迟。

说实话,调试这让我浪费了一些时间,我仍然不明白 sn-p a) 的问题。我是否滥用了任务模块?我检查了文档,找不到任何可以向我解释此问题的内容。

编辑: sn-p a) 的输出

test1
test2
test3

【问题讨论】:

  • 您有 2 个 "test3" 调试输出,您介意更改其中任何一个并确认任务正在打印一行 before HTTPoison 请求吗?
  • @mudasobwa 完成
  • @PawełDuda 你能尝试创建一个最小的可重现示例来显示这种行为吗?

标签: elixir httpoison


【解决方案1】:

我可以看到您的 HTTP 请求的超时值很高。该任务的默认超时值为5_000 ms,因此该任务很可能在请求完成之前超时。随后任务被终止,您永远看不到输出。 Task.await/2 函数接受超时作为第二个参数。

无论如何,您应该会看到任务超时错误。也许你忽略了一些输出?

【讨论】:

  • 我真的希望这里是这种情况,但任务似乎没有超时......即使某些事情需要超过 5 秒,它最终也会正确完成。此外,如果超时,程序应该继续通过Task.await 并打印“test4”,这不会发生:/
  • 这两件事都不是真的。超时后任务被杀死,任务进程立即终止。此外,由于Task.async/1 的调用者与任务相关联,当Task.await/2 中的任务超时时,进程也会终止,因此“test4”永远不会出现。
  • 你是对的。我将超时时间增加到100_000,现在它的行为似乎正确:) 谢谢,我肯定会花更多时间来跟踪这个。
猜你喜欢
  • 2015-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-21
  • 2018-09-16
  • 2010-10-08
  • 2017-01-07
  • 2015-01-27
相关资源
最近更新 更多