Are there any best practices for this? When starting the LiveView process, start a data processing cooperative process for it at the same time?

I asked this in slack, but I’d like to ask it again here as well. Because I think it’s a worthwhile discussion.

The core question is how we should split some of the asynchronous logic out of the LiveView.

We now have a scenario like this. When the user opens the page, we asynchronously initiate a lot of time-consuming api requests. After these requests, we will provide the user with some action buttons based on the returned data.
At present, my design is to allow users to quickly open the page and then send requests concurrently. So I put these api_calls in the LiveView, like this:

pid = self()

Task.async(fn ->
  case api_call(_) do
    [] ->
      send(pid, {:some_error, "some error"})

    correct_result ->
      send(pid, {:correct_result, correct_result})
  end
end)

It’s fine if there are few such api_calls, but if the returned data is interdependent, it makes this LiveView very complicated, because it means I need to manage multiple concurrent timelines.
So my idea is to put these api_calls to a separate process that provides some api that triggers the request. We can start this process during mount, and then the LiveView just receives the messages processed by that process, which will make my LiveView much cleaner.

Before introducing yet another process and lifecycle I’d probably look at abstracting the code into a separate module. That will likely give you a good chunk of “a much cleaner LV” without the additional complexities of having another process.

2 Likes