Design: recursive function call that could crash

So I have a function that calls it self after doing some work. I’m starting it like this when my application starts:

Task.Supervisor.start_child(MyApp.TaskSupervisor, fn ->
  recurse()
end)

def recurse() do
  # do some work that might crash
  recurse()
end

I’ve also started that supervisor:

children = [
  supervisor(Task.Supervisor, [[name: MyApp.TaskSupervisor]])
]
opts = [strategy: :one_for_one, name: MyApp.Supervisor]
started = Supervisor.start_link(children, opts)

I’m also doing a recursive call somewhere else that actually passes a map to each recursive call and I’d like to do the same thing there but also have access to that map/state so that I could continue recursing where it left off.

How could I customize the task supervisor so that I could send a notification when it crashes and restart the recursion? Is this even the correct design? Should I instead create a GenServer that calls itself recursively? Is a GenServer recursively calling itself a common way to have a continually running task?

1 Like
  • After each recursion, dump the map to JSON file on disk (use Poison), or to database if you have that setup.
  • Create another process to maintain state.
1 Like

Maybe try gen_retry? It’s designed to retry a process that raises an error on failure. I use it for API calls. It supports a process directly, and synchronous and asynchronous tasks.

1 Like