Why do a brutal kill for a process performing an HTTP request?

I am reading the book Programming Phoenix 1.4. There is a task, we want to connect Wolfram API, and if it does not respond within 10 second, kill the process:

  |> Enum.map(&async_query(&1, query, opts))
  |> Task.yield_many(timeout)
  |> Enum.map(fn {task, res} -> res || Task.shutdown(task, :brutal_kill) end)

But wouldn’t it be easier to specify a timeout for :httpc and let the process terminate normally? Maybe there is a best practice for killing such a process or it was made for illustration purposes?

Yeah in general if you can guarantee that the code you execute inside a task finishes within a given timeframe, then you can likely get rid of the Task.shutdown/2. On the other hand, it can also be seen as a “safety measure”, making sure that you do actually terminate potentially-stuck processes, avoiding leaks.