Genserver state change during handle_info or handle_call

The name of the picture


Genserver state change during handle_info or handle_call



Suppose I have a simple genserver that mantains a simple :queue as it's state. Items are continually being added with handle_cast. Every 5 seconds I process the queue with Process.send_after. That call gets handled with a call back to handle_info with the current state. The queue gets processed and emptied then a new empty queue is applied as the current state of the genserver.



My question is this:
What happens when calls come into genserver while the queue is being processed? Since I return a new empty queue to handle_info {:noreply, :queue.new} will that write over items that were being added while I was processing the queue? Or will the genserver casts be themselfs queued up then allowed to finish once handle_info is done?
Basically I am concerned about missing items during handle_info.



Code:


defmodule TcpClient.Queue do
use GenServer
require Logger

def start_link do
queue = :queue.new()
GenServer.start_link(__MODULE__, queue, name: {:global, :tcp_queue})
end

def init(queue) do
Logger.debug("Starting up Queue")
schedule_work()
{:ok, queue}
end

def enqueue(msg) do
Logger.debug("Item Added")
GenServer.cast(whereis(), {:enqueue, msg})
end

defp schedule_work() do
Process.send_after(self(), :work, 1 * 1 * 300)
end

def handle_cast({:enqueue, msg}, state) do
{:noreply, :queue.in(msg, state)}
end

def handle_info(:work, queue) do
case :queue.is_empty(queue) do
true ->
Logger.debug("No items to Process")
nil

false ->
Logger.debug("Processing Queue")

:queue.to_list(queue)
|> Enum.map(&TcpClient.Repo.add_message(&1))

queue = :queue.new()
end

schedule_work()
{:noreply, queue}
end

def whereis() do
:global.whereis_name(:tcp_queue)
end
end




1 Answer
1



Incoming messages are being put into process mailbox and are not processed until the process has returned from previous handle_***. You are risking to overflow your process’ mailbox, not to miss some messages.


handle_***



To prevent this, GenStage was explicitly created by Elixir Core team to fight back pressure.


GenStage






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Arduino Mega cannot recieve any sketches, stk500_recv() programmer is not responding

Visual Studio Code: How to configure includePath for better IntelliSense results

Blogger: Contempo template have managed to get the posts to post in full but there is still a “snippet” of the post at the bottom of each full post