I would like to perform an action periodically, and I am looking for the simplest reasonable way to do this.
As an example, let’s say I want to delete old entries from a db table, every few hours. The action is idempotent, relatively inexpensive, precision “doesn’t matter,” and concurrent executions of multiple runs (e.g. from multiple replicas of the service) is not a problem (db transactions will handle them safely).
A commonly recommended approach for doing this seems to be a variation of using a GenServer with send_after (or, I suppose, spinning up an oban job;).
This makes a lot of sense, but I coded up just running an infinite supervised “do”+“sleep” recursion, and it seems to work, and it seems ridiculously concise and simple, and I can’t explain to myself why that wouldn’t be enough.
Is there any reason why I shouldn’t do this? ; )
If you have any thoughts / guidance on this, I would much appreciate them!
Thank you!
PS An example of what this might look like in code:
application.ex
(starts the task, restart: :permanent
):
defmodule MyApp.Application do
def start(_type, _args) do
children = [
...,
Supervisor.child_spec(
{Task, fn -> MyApp.Sweeper.delete_old_data(sleep_ms) end},
restart: :permanent
),
...
]
Supervisor.start_link(children, strategy: :one_for_one, name: MyApp.Supervisor)
end
end
where delete_old_data()
just keeps doing the thing and sleeping, forever:
defmodule MyApp.Sweeper do
def delete_old_data(wait_ms) do
... delete old things ...
Process.sleep(wait_ms)
delete_old_data(wait_ms)
end
end