PhoenixKitCatalogue. Workers. TranslationSweepWorker
(PhoenixKitCatalogue v0.44.2)
Copy Markdown
View Source
Opt-in, self-rescheduling Oban worker that tops up catalogue AI
translations: on every tick it enqueues one PhoenixKitAI.TranslateWorker
job per (resource, target language) pair currently :missing or
:stale — :unknown is never picked up automatically (design source
doc §4.1: an operator decides that pair's fate explicitly).
Settings (PhoenixKitCatalogue.Web.Settings, Task 4):
catalogue_translation_sweep_enabled— off by default; a disabled tick still reschedules its successor, it just does no work.catalogue_translation_sweep_interval_minutes— gap to the next tick.catalogue_translation_sweep_langs— target languages to consider.catalogue_translation_sweep_max_per_run— enqueue cap for one tick, counted in jobs (across every resource type) not resources.
Self-rescheduling
The very first action of perform/1 is scheduling the NEXT tick —
before any of the tick's own work runs — so a crashed or slow tick
never breaks the chain. Uniqueness (period: :infinity, states: [:available, :scheduled]) keeps at most one pending tick in the
queue at a time; the explicit state list (rather than Oban's default,
which references :suspended) sidesteps the 22P02 landmine
PhoenixKitAI.Translations and PhoenixKitCatalogue.Workers.PdfExtractor
already document for hosts whose oban_job_state enum predates that
value. max_attempts: 1 — retrying a missed tick is pointless, the
next one is already scheduled.
ensure_scheduled/0 seeds the very first tick at boot (see
PhoenixKitCatalogue.children/0) and is safe to call again any time
(e.g. a future settings save) — the same uniqueness collapses repeat
calls to the one pending job.
Summary
Functions
Resolves the AI endpoint and per-resource-type prompt uuids, the same way
every sweep tick does: Translations.available?/0 ALONE isn't enough (it
doesn't verify the configured default endpoint still exists/is enabled) —
the double check the design source calls for (§4.3 step 2).
Ensures exactly one sweep tick is available/scheduled. Called from the
boot-time task registered in children/0; concurrent callers (boot,
a future settings save, the tick itself) all collapse onto the same
unique row.
Boot-time gate for ensure_scheduled/0: seeds the chain only if the
sweep is already enabled, so a host that has never turned it on gets no
ticking job row. Web.Settings.update_sweep_enabled/1 calls
ensure_scheduled/0 unconditionally when it flips the setting to
true, so the chain always starts exactly when a host first opts in —
at boot (already enabled from a previous save) or from that save
itself.
The ai_translatables/0 resource_type string for a TranslationStatus.list/2 type atom.
Functions
@spec endpoint_and_prompts() :: {:ok, String.t(), %{required(String.t()) => String.t()}} | :unavailable
Resolves the AI endpoint and per-resource-type prompt uuids, the same way
every sweep tick does: Translations.available?/0 ALONE isn't enough (it
doesn't verify the configured default endpoint still exists/is enabled) —
the double check the design source calls for (§4.3 step 2).
Public so Web.TranslationsLive's manual "Translate" / bulk actions share
this exact resolution path with the automatic sweep tick, rather than
re-deriving which prompt belongs to which resource type a second time.
@spec ensure_scheduled() :: {:ok, Oban.Job.t()} | {:error, term()}
Ensures exactly one sweep tick is available/scheduled. Called from the
boot-time task registered in children/0; concurrent callers (boot,
a future settings save, the tick itself) all collapse onto the same
unique row.
@spec ensure_scheduled_if_enabled() :: {:ok, Oban.Job.t()} | {:error, term()} | :skipped
Boot-time gate for ensure_scheduled/0: seeds the chain only if the
sweep is already enabled, so a host that has never turned it on gets no
ticking job row. Web.Settings.update_sweep_enabled/1 calls
ensure_scheduled/0 unconditionally when it flips the setting to
true, so the chain always starts exactly when a host first opts in —
at boot (already enabled from a previous save) or from that save
itself.
@spec resource_type_for(:item | :category | :set_label | :set_value) :: String.t()
The ai_translatables/0 resource_type string for a TranslationStatus.list/2 type atom.