I’m looking for clarity on the benefits of GenServers. At first I thought they could be used to process asynchronous work via
handle_case, but it seems like the popular literature, some by Jose himself, advocates against using casts in favor of the synchronous
call. If GenServers are meant to be used to handle synchronous code, what’s the point? I have trouble how I’d benefit more by using them over a Task.
Consider the following classic breakfast scenario. To have breakfast, I need to do the following things:
- Make toast
- Cook eggs
- Butter the toast
- Pour orange juice
- Plate the eggs and toast
To do this, (1,3), 2, and 4 could be run as separate tasks. 5 could await 1, 2, and 3, and 6 could await 1-5:
oj_task = Task.async(fn -> pour_oj() end) [ Task.async(fn -> make_toast() |> butter_toast end), Task.async(fn -> make_eggs() end) ] |> Enum.map(&Task.await/1) plate_task = plate_eggs_and_toast() [ oj_task, plate_task] |> Enum.map(&Task.await/1) |> eat()
How would I be able to do this via GenServers?
It’s possible that I’m missing some foundational understanding here. I just don’t see the utility of using
call when a
cast would do the trick. Please help clarify. Thank you!