Update state of an Agent at a specific time using Process.send_after/4

Hi all,

I am having some trouble finding resources on how to use Process.send_after/4 to update an Agent. I’m exploring a use case where I update a bunch of Agents each hour, and have all the changes be applied at the same time. In my head, I thought it would be pretty easy to use Process.send_after/4 to do so, but after working on the implementation, I discovered that I’m not sure what message to send to the process. I realize that under the hood, Agent is just a simple GenServer, and after looking at the source code the update is implemented as so:

  def update(agent, fun, timeout \\ 5000) when is_function(fun, 1) do
    GenServer.call(agent, {:update, fun}, timeout)

With a server implementation of:

  def handle_call({:update, fun}, _from, state) do
    {:reply, :ok, run(fun, [state])}

But, unless I’m mistake, I think if I were to use Process.send_after(pid, {:update, fn _ -> new_value end}, ms_until_update), it wouldn’t be handled by the handle_call/3 function shown above, because in a normal GenServer it would instead be handled by a (non-existent) handle_info/2 function. So I guess I’m not sure how to go about doing this? Or even if this is the right way/thinking for updating the state of a bunch of Agents at the same time?

I realize the easy alternative is just implementing my own version of agent that supports this handle_info/2 call :man_shrugging:

I’m looking forward to hearing all y’alls input!


Or turn your Agents into GenServers.

1 Like

Does it have to be an Agent in particular? A normal GenServer handles that just fine.

1 Like

Yeah, I am realizing that probably the best solution is to turn my agent into a simple genserver that handles this function. I think as I wrote the question, that solution was slowly appearing in my brain :joy: anyways, I can go ahead and do that, and let you guys know how well that works.

For some reason I was thinking it would be easier to abuse the internal behavior of the genserver and send it a {:cast, {:update, myfun}} message or something that triggered the existing Agent update function. But likely that would not be very maintainable, because of the hack-y nature.