resolved bug where source metadata worker could call itself in an infinite loop

This commit is contained in:
Kieran Eglin 2024-03-14 15:15:43 -07:00
parent 0de5ea901d
commit 5d4799ab0a
No known key found for this signature in database
GPG key ID: 193984967FCF432D
2 changed files with 31 additions and 2 deletions

View file

@ -4,7 +4,10 @@ defmodule Pinchflat.Metadata.SourceMetadataStorageWorker do
use Oban.Worker, use Oban.Worker,
queue: :remote_metadata, queue: :remote_metadata,
tags: ["media_source", "source_metadata", "remote_metadata"], tags: ["media_source", "source_metadata", "remote_metadata"],
max_attempts: 1 max_attempts: 1,
# This is the only thing stopping this job from calling itself
# in an infinite loop.
unique: [period: 600]
alias __MODULE__ alias __MODULE__
alias Pinchflat.Repo alias Pinchflat.Repo
@ -27,16 +30,19 @@ defmodule Pinchflat.Metadata.SourceMetadataStorageWorker do
|> Tasks.create_job_with_task(source) |> Tasks.create_job_with_task(source)
end end
@impl Oban.Worker
@doc """ @doc """
Fetches and stores metadata for a source in the secret metadata location. Fetches and stores metadata for a source in the secret metadata location.
Returns :ok Returns :ok
""" """
@impl Oban.Worker
def perform(%Oban.Job{args: %{"id" => source_id}}) do def perform(%Oban.Job{args: %{"id" => source_id}}) do
source = Repo.preload(Sources.get_source!(source_id), :metadata) source = Repo.preload(Sources.get_source!(source_id), :metadata)
{:ok, metadata} = MediaCollection.get_source_metadata(source.original_url) {:ok, metadata} = MediaCollection.get_source_metadata(source.original_url)
# Since updating a source kicks this job off again, we enforce job uniqueness (above)
# to once, per source, per x minutes. This is to prevent a job from calling itself
# in an infinite loop.
Sources.update_source(source, %{ Sources.update_source(source, %{
metadata: %{ metadata: %{
metadata_filepath: MetadataFileHelpers.compress_and_store_metadata_for(source, metadata) metadata_filepath: MetadataFileHelpers.compress_and_store_metadata_for(source, metadata)

View file

@ -51,5 +51,28 @@ defmodule Pinchflat.Metadata.SourceMetadataStorageWorkerTest do
assert metadata == %{"title" => "test"} assert metadata == %{"title" => "test"}
end end
test "won't call itself in an infinite loop" do
stub(YtDlpRunnerMock, :run, fn _url, _opts, _ot -> {:ok, "{}"} end)
source = source_fixture()
perform_job(SourceMetadataStorageWorker, %{id: source.id})
perform_job(SourceMetadataStorageWorker, %{id: source.id})
assert [_] = all_enqueued(worker: SourceMetadataStorageWorker)
end
test "doesn't prevent over source jobs from running" do
stub(YtDlpRunnerMock, :run, fn _url, _opts, _ot -> {:ok, "{}"} end)
source_1 = source_fixture()
source_2 = source_fixture()
perform_job(SourceMetadataStorageWorker, %{id: source_1.id})
perform_job(SourceMetadataStorageWorker, %{id: source_1.id})
perform_job(SourceMetadataStorageWorker, %{id: source_2.id})
perform_job(SourceMetadataStorageWorker, %{id: source_2.id})
assert [_, _] = all_enqueued(worker: SourceMetadataStorageWorker)
end
end end
end end