处理:DOWN和#Reference< ...>任务超时

时间:2018-03-18 12:08:36

标签: elixir

我使用Task.async/3生成一个函数,并使用Task.yield/2获取超时结果。函数完成后,调用进程会收到两条消息:

{#Reference<0.2781211517.3250323457.144521>, the_result_of_the_function}

其中#ReferenceTask.async/3

返回的监视器的引用
{:DOWN, #Reference<0.2781211517.3250323457.144521>, :process, #PID<0.24500.0>, :normal}

由监视器发送,以通知受监视的进程(任务)已关闭。

如果任务在超时之前完成Task.yield/2会将这些消息从邮箱中取出并返回正确的结果。但是,如果任务在超时后完成Task.yield/2将返回nil,当这两条消息到达时,程序流已经在其他位置。

我实现了两个handle_info处理程序,以便从邮箱中获取这些邮件。然而,这可能是一个坏主意,因为我无法仅从过期的任务中获取消息,(我也没有看到任何方式注册&#34; #Reference对于已经超时的任务,我可能会在Task.yield/2读取之前删除有效的按摩。

我错过了什么以及如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

Task.yield/2的文档提出了以下方法:

  

如果在收到来自任务的消息之前时间用完,此功能将返回nil并且监视器将保持活动状态。 [...]如果您打算在超时毫秒内没有响应任务,那么您应该将其与shutdown/1链接在一起,如下所示:

case Task.yield(task, timeout) || Task.shutdown(task) do
  {:ok, result} ->
    result
  nil ->
    Logger.warn "Failed to get a result in #{timeout}ms"
    nil
end