CherryPoppins

CherryPoppins

Nesting Task.Supervisor.async_stream bad idea?

So im looking to do something like below where I get a list of posts from the db and then run an api call on each post's comments and i want it to all happen as concurrently as possible. Is nesting task bad practice?

defmodule MyApp.ObanWorker do
  def perform do
    posts = MyApp.Repo.all(Posts)

    MyTaskSupervisor
    |> Task.Supervisor.async_stream(posts, &MyApp.ApiClient.do_it/1)
    |> List.flatten()
    |> Enum.each(fn {_, message} -> Logger.info(message) end)

    :ok
  end
end

defmodule MyApp.ApiClient do
  def do_it(%{comments: comments} = post) do
    MyTaskSupervisor
    |> Task.Supervisor.async_stream(comments, &make_call/1)
    |> Enum.filter(&(elem(&1, 0) == :error))
    
  end

  def make_call(comment) do
    result = # ...make api request
    
    case result do
      {:ok, %{status: 200}} -> {:ok, "good job."}
      _ -> {:error, "not good for #{comment}."}
    end
  end
end

Most Liked

gregvaughn

gregvaughn

I wouldn’t nest them. That would increase the complexity of tuning via max_concurrency. I would start with a list of comments that belong to the desired posts in the original query.

dimitarvp

dimitarvp

Don’t nest them because you’re likely dealing with increased copying of values and with parallelism guarantees that will no longer hold true (i.e. originally you made the code to do no more than 20 tasks in parallel but with nesting that can balloon further).

Alternative thing you can do is to separate all the tasks and queue them one by one through, say, commanding a GenServer to pull them one by one from a queue, and then each task can use Task.async_stream (with only one level and no nesting).

al2o3cr

al2o3cr

One thing to watch out for with tasks is copying large data structures - in this case, comments presumably has a lot of entries (thus the need for concurrency) so copying it is expensive.

Where Next?

Popular in Questions Top

vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
PeterCarter
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New
sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New

Other popular topics Top

grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 54092 488
New
Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New

We're in Beta

About us Mission Statement