top | item 40562662

(no title)

dasyatidprime | 1 year ago

Task.await tries to exit the calling process when the timeout hits, but IEx traps the exit in that process, so it doesn't terminate and thus the linked task process doesn't either, I think? If I do all of this wrapped in another task, rather than directly in IEx, then I observe the innermost process get terminated by the process link after the intervening one doesn't trap the exit.

Relevant from https://hexdocs.pm/elixir/1.4.5/Task.html, which you've probably already seen:

> If the timeout is exceeded, await will exit; however, the task will continue to run. When the calling process exits, its exit signal will terminate the task if it is not trapping exits.

discuss

order

dasyatidprime|1 year ago

Bletch, I had the wrong version of the documentation bookmarked—here's the revised relevant sentences from https://hexdocs.pm/elixir/1.16.2/Task.html#await/2 (my system has 1.16.2):

> If the timeout is exceeded, then the caller process will exit. If the task process is linked to the caller process which is the case when a task is started with async, then the task process will also exit.

Reasoning is the same though; self() preceding/following it in the IEx session still shows the same evaluator process alive.

jonnycat|1 year ago

Good call - I think you're right about IEx trapping the exit. The confusing part is that it still logs out this message:

  ** (exit) exited in: Task.await(%Task{mfa: {:erlang, :apply, 2}, owner: #PID<0.954.0>, pid: #PID<0.964.0>, ref: #Reference<0.1455049351.208994307.4788>}, 1)
    ** (EXIT) time out
    (elixir 1.14.3) lib/task.ex:830: Task.await/2

dasyatidprime|1 year ago

Yeah, I agree that the way that comes out is really awkward. The first line there is reporting the context from in the Task module (because task.ex includes it explicitly in the exit call), and then the second is reporting a strerror-like translation of the :timeout reason, but the lines aren't clearly linked together that way and look more like chained events. All of the %Task{} stuff of course is just the inspection of the argument, but if your eye jumps to the “pid” part it can look like it's reporting that that's the exiting process even though it's not. And then the part where the first “exited” is written in past tense as though the exit happened, when in fact it's describing what the trap just caused to not actually fully happen, is probably the most confusing of all.