1
votes

I am setting up a GenServer that runs every hour to cache data. I followed the example José Valim posted is response to a question about how to do this.

How to run some code every few hours in Phoenix framework?

It works great except that if the interval I gave the call to Process.send_after/3 is a module attribute it does not run. Does anyone have insights as to why this might be?

So the following does not work but if in the calls to Process.send_after/3 I replace @interval with 60 * 60 * 1000 it runs as expected (this is essentially the code from the other SO post above):

defmodule MyApp.Periodically do
  use GenServer

  def start_link do
    GenServer.start_link(__MODULE__, %{})
  end

  @interval 60 * 60 * 1000

  def init(state) do
    Process.send_after(self(), :work, @interval)
    {:ok, state}
  end

  def handle_info(:work, state) do
    # Begin caching the new data.
    MyApp.CacheManager.cache_new_data()

    # Start the timer again
    Process.send_after(self(), :work, @interval)
    {:noreply, state}
  end
end
1
I use module attributes with send_after quite often. Thus, I am sure it should work. Try outputting the interval before you use it and see what it is: IO.inspect @interval. It is possible does not have the value you think it does.Jason Harrelson
Your code works as listed in the question. I changed it to 1 * 2 * 1000 for quick testing, but it does run.CoderDennis
@JasonHarrelson Just tried it again and it is working. I must have not compiled again and was running stale code with a very long interval so I wasn't catching it. Thanks for the help.ascrookes

1 Answers

1
votes

Have you posted the exact code you're using? I just tried this:

iex(1)> defmodule T do
...(1)>  @interval 60 * 60 * 1000
...(1)>  @calc_int (60 * 60 * 1000)
...(1)>  def t do
...(1)>     IO.puts @interval
...(1)>     IO.puts @calc_int
...(1)>  end
...(1)> end
{:module, T,
 <<70, 79, 82, 49, 0, 0, 4, 212, 66, 69, 65, 77, 69, 120, 68, 99, 0, 0, 0, 124, 131, 104, 2, 100, 0, 14, 101, 108, 105, 120, 105, 114, 95, 100, 111, 99, 115, 95, 118, 49, 108, 0, 0, 0, 4, 104, 2, ...>>,
 {:t, 0}}
iex(2)> T.t
3600000
3600000
:ok

because I thought the issue might be that the product wasn't being calculated before the call but judging by that output I don't think that'd be the issue. But we need to see your exact code in order to figure out what's wrong.