I have two dynamically supervised GenServers that interact with each other.
I have a handle_info callback:
def handle_info({:event, payload}, state) do
model = PS.get_process_model(state.model_name)
if model.events do
[event] = model.events
if event.message_selector.(payload) do
exit_task(event.exit_task, state) # <========
else
state
end
else
state
end
{:noreply, state}
end
The code for exit_task/2 is:
defp exit_task(task_name, state) do
task = Enum.find(Map.values(state.open_tasks), fn t -> t.name == task_name end)
if task.type == :sub_process do
complete_on_task_exit_event(task.sub_process_pid) # <=======
end
Map.put(state, :completed_tasks, [task | state.completed_tasks])
|> Map.put(:open_tasks, Map.delete(state.open_tasks, task.uid))
|> execute_process()
end
Initially, I had complete_on_task_exit_event/1 as a GenServer call function.
Strangely, with the GenServer.call implementation, the code in the exit_task/2 after the call to complete_on_task_exit/1 did not get executed, i.e. this code:
Map.put(state, :completed_tasks, [task | state.completed_tasks])
|> Map.put(:open_tasks, Map.delete(state.open_tasks, task.uid))
|> execute_process()
I don’t mean that execution hung. What it seems like is that the function completed execution and just skipped the code above.
When I changed complete_on_task_exit_event/1 to a GenServer cast function, the previously unexecuted code did get executed.
Note that this isn’t a case recursively calling the same GenServer. The call to complete_on_task_exit_event/1 was on a separate GenServer instance.
I hope I’ve explained this sufficiently.
Can anyone offer an explanation?
Thanks