1

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
Community
  • 1
  • 1
ascrookes
  • 433
  • 5
  • 12
  • 2
    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 Mar 09 '16 at 15:49
  • 3
    Your code works as listed in the question. I changed it to `1 * 2 * 1000` for quick testing, but it does run. – CoderDennis Mar 09 '16 at 17:05
  • @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 Mar 09 '16 at 23:03

1 Answers1

1

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.

Onorio Catenacci
  • 14,928
  • 14
  • 81
  • 132
  • Yeah this is the same code except change MyApp to Cymbal. I use module attributes in other places in my project and those all work totally fine. It is just in this instance of using it with a GenServer. – ascrookes Mar 09 '16 at 22:58
  • 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 Mar 09 '16 at 23:03