Built a genserver to rename old jobs on boot
This commit is contained in:
parent
abe559c41b
commit
66c1903a41
7 changed files with 502 additions and 27 deletions
401
dump_all.sql
Normal file
401
dump_all.sql
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -11,8 +11,9 @@ defmodule Pinchflat.Application do
|
|||
PinchflatWeb.Telemetry,
|
||||
Pinchflat.Repo,
|
||||
# Must be before startup tasks
|
||||
Pinchflat.Boot.PreJobStartupTasks,
|
||||
{Oban, Application.fetch_env!(:pinchflat, Oban)},
|
||||
Pinchflat.Boot.StartupTasks,
|
||||
Pinchflat.Boot.PostJobStartupTasks,
|
||||
{DNSCluster, query: Application.get_env(:pinchflat, :dns_cluster_query) || :ignore},
|
||||
{Phoenix.PubSub, name: Pinchflat.PubSub},
|
||||
# Start the Finch HTTP client for sending emails
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
defmodule Pinchflat.Boot.StartupTasks do
|
||||
defmodule Pinchflat.Boot.PostJobStartupTasks do
|
||||
@moduledoc """
|
||||
This module is responsible for running startup tasks on app boot
|
||||
AFTER the job runner has initiallized.
|
||||
|
|
@ -12,7 +12,6 @@ defmodule Pinchflat.Boot.StartupTasks do
|
|||
import Ecto.Query, warn: false
|
||||
|
||||
alias Pinchflat.Repo
|
||||
alias Pinchflat.Settings
|
||||
alias Pinchflat.Boot.DataBackfillWorker
|
||||
|
||||
def start_link(opts \\ []) do
|
||||
|
|
@ -30,17 +29,11 @@ defmodule Pinchflat.Boot.StartupTasks do
|
|||
"""
|
||||
@impl true
|
||||
def init(state) do
|
||||
apply_default_settings()
|
||||
enqueue_backfill_worker()
|
||||
|
||||
{:ok, state}
|
||||
end
|
||||
|
||||
defp apply_default_settings do
|
||||
Settings.fetch!(:onboarding, true)
|
||||
Settings.fetch!(:pro_enabled, false)
|
||||
end
|
||||
|
||||
defp enqueue_backfill_worker do
|
||||
DataBackfillWorker.cancel_pending_backfill_jobs()
|
||||
|
||||
73
lib/pinchflat/boot/pre_job_startup_tasks.ex
Normal file
73
lib/pinchflat/boot/pre_job_startup_tasks.ex
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
defmodule Pinchflat.Boot.PreJobStartupTasks do
|
||||
@moduledoc """
|
||||
This module is responsible for running startup tasks on app boot
|
||||
BEFORE the job runner has initiallized.
|
||||
|
||||
It's a GenServer because that plays REALLY nicely with the existing
|
||||
Phoenix supervision tree.
|
||||
"""
|
||||
|
||||
# restart: :temporary means that this process will never be restarted (ie: will run once and then die)
|
||||
use GenServer, restart: :temporary
|
||||
import Ecto.Query, warn: false
|
||||
require Logger
|
||||
|
||||
alias Pinchflat.Repo
|
||||
alias Pinchflat.Settings
|
||||
|
||||
def start_link(opts \\ []) do
|
||||
GenServer.start_link(__MODULE__, %{}, opts)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Runs application startup tasks.
|
||||
|
||||
Any code defined here will run every time the application starts. You must
|
||||
make sure that the code is idempotent and safe to run multiple times.
|
||||
|
||||
This is a good place to set up default settings, create initial records, stuff like that.
|
||||
Should be fast - anything with the potential to be slow should be kicked off as a job instead.
|
||||
"""
|
||||
@impl true
|
||||
def init(state) do
|
||||
apply_default_settings()
|
||||
rename_old_job_workers()
|
||||
|
||||
{:ok, state}
|
||||
end
|
||||
|
||||
defp apply_default_settings do
|
||||
Settings.fetch!(:onboarding, true)
|
||||
Settings.fetch!(:pro_enabled, false)
|
||||
end
|
||||
|
||||
# As part of a large refactor, I ended up moving a bunch of workers around. This
|
||||
# is a problem because the workers are stored in the database and the runner
|
||||
# will try to run the OLD jobs. This is also why these tasks run before the job
|
||||
# runner starts up.
|
||||
#
|
||||
# Can be removed after a few months (created: 2024-03-12)
|
||||
defp rename_old_job_workers do
|
||||
# [ [old_name, new_name], ...]
|
||||
rename_map = [
|
||||
["Pinchflat.Workers.MediaIndexingWorker", "Pinchflat.FastIndexing.MediaIndexingWorker"],
|
||||
["Pinchflat.Workers.MediaDownloadWorker", "Pinchflat.Downloading.MediaDownloadWorker"],
|
||||
["Pinchflat.Workers.FilesystemDataWorker", "Pinchflat.Filesystem.FilesystemDataWorker"],
|
||||
["Pinchflat.Workers.FastIndexingWorker", "Pinchflat.FastIndexing.FastIndexingWorker"],
|
||||
["Pinchflat.Workers.MediaCollectionIndexingWorker", "Pinchflat.SlowIndexing.MediaCollectionIndexingWorker"],
|
||||
["Pinchflat.Workers.DataBackfillWorker", "Pinchflat.Boot.DataBackfillWorker"]
|
||||
]
|
||||
|
||||
jobs_renamed =
|
||||
Enum.reduce(rename_map, 0, fn [old_name, new_name], acc ->
|
||||
{count, _} =
|
||||
Oban.Job
|
||||
|> where(worker: ^old_name)
|
||||
|> Repo.update_all(set: [worker: new_name])
|
||||
|
||||
acc + count
|
||||
end)
|
||||
|
||||
Logger.info("Renamed #{jobs_renamed} old job workers")
|
||||
end
|
||||
end
|
||||
|
|
@ -1,8 +1,6 @@
|
|||
defmodule Pinchflat.FastIndexing.MediaIndexingWorker do
|
||||
@moduledoc false
|
||||
|
||||
# TODO: make a startup task to rename all existing workers so they still run
|
||||
|
||||
use Oban.Worker,
|
||||
queue: :media_indexing,
|
||||
unique: [period: :infinity, states: [:available, :scheduled, :retryable]],
|
||||
|
|
|
|||
25
test/pinchflat/boot/pre_job_startup_tasks_test.exs
Normal file
25
test/pinchflat/boot/pre_job_startup_tasks_test.exs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
defmodule Pinchflat.Boot.PreJobStartupTasksTest do
|
||||
use Pinchflat.DataCase
|
||||
|
||||
alias Pinchflat.Settings
|
||||
alias Pinchflat.Settings.Setting
|
||||
alias Pinchflat.Boot.PreJobStartupTasks
|
||||
|
||||
describe "apply_default_settings" do
|
||||
setup do
|
||||
Repo.delete_all(Setting)
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
test "sets default settings" do
|
||||
assert_raise Ecto.NoResultsError, fn -> Settings.get!(:onboarding) end
|
||||
assert_raise Ecto.NoResultsError, fn -> Settings.get!(:pro_enabled) end
|
||||
|
||||
PreJobStartupTasks.start_link()
|
||||
|
||||
assert Settings.get!(:onboarding)
|
||||
refute Settings.get!(:pro_enabled)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
defmodule Pinchflat.Boot.StartupTasksTest do
|
||||
use Pinchflat.DataCase
|
||||
|
||||
alias Pinchflat.Settings
|
||||
|
||||
# Since this runs on app boot (even in the test env),
|
||||
# any actions in the `init/1` function will already have
|
||||
# run. So we can only test the side effects of those actions,
|
||||
# rather than the actions themselves.
|
||||
|
||||
describe "apply_default_settings" do
|
||||
test "sets default settings" do
|
||||
assert Settings.get!(:onboarding) == true
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Reference in a new issue