GenServer advice needed - relationship between handle_call and handle_info that use the same state

Say I have a message queue implemented as a GenServer, something like this

#... def start_link ...

def init(state) do
  {:ok, schedule(state)}
end

# schedule processing every 500 ms
defp schedule(state) do
  Process.send_after(self(), :process, 500)
  state
end

def handle_info(:process, state) do
  {:noreply, process_queue(state)}
end

# catch all handle_info

def process_queue(state) do 
    # concurrently processes each entry and deletes it from the state
    # schedule(state)
end

def put(data) do
  GenServer.call(__MODULE__, {:put, entry})
end

def handle_call({:put, entry}, _from, state) do
  {:reply, :ok, [entry | state]}
end

The question is about the relationship between handle_call and handle_info that both use the same state. From what I understand there is no way the state breaks, meaning while process_queue does its job (which may take a while) any put calling handle_call will have to wait, is that right?

If I want put to return immediately and add entries to queue after handle_info is done, I’d have to switch from call to cast, and I’m good?

Is there a nicer / simpler approach to achieve that or is this one good? Shouldn’t I handle such state using ETS (that’s what I’m switching from at the moment)?