defmodule Mix.Tasks.Relyra.RefreshDue do
@moduledoc """
Runs any due Phase 21 scheduled metadata refreshes once.
Suitable for system cron, `kubectl run`, fly.io scheduled machines, and
any other host scheduler that prefers a CLI invocation over an Oban
worker. Adopters who use Oban add the documented Cron one-liner
instead — see the README "Operations" section.
mix relyra.refresh_due --repo MyApp.Repo
Returns `:ok` on a clean tick (including the no-due-sources case, which
emits the `[:relyra, :saml, :metadata, :auto_refresh, :skipped]` event).
"""
@shortdoc "Refresh any metadata sources whose schedule is due."
use Mix.Task
@impl true
def run(args) do
Mix.Task.run("app.start")
{opts, _argv, _invalid} =
OptionParser.parse(args,
strict: [repo: :string],
aliases: [r: :repo]
)
repo_string =
Keyword.get(opts, :repo) ||
Mix.raise("--repo is required: mix relyra.refresh_due --repo MyApp.Repo")
repo =
try do
String.to_existing_atom(repo_string)
rescue
ArgumentError -> Mix.raise("Repo module #{repo_string} is not loaded")
end
case Relyra.Metadata.Scheduler.run_due(repo, []) do
{:ok, results} when is_map(results) ->
Mix.shell().info("relyra.refresh_due: #{map_size(results)} sources processed.")
:ok
other ->
# Defensive fallback for the Ecto-absent compile lane (the
# Scheduler stub returns `{:error, %Relyra.Error{}}`); the
# present-Ecto body returns only `{:ok, _}` so the typer cannot
# see this path.
Mix.raise("relyra.refresh_due failed: " <> inspect(other))
end
end
end