RichMedia backfill processing through Oban
This commit is contained in:
parent
4dfa50f256
commit
17d04ccc8b
10 changed files with 59 additions and 60 deletions
|
|
@ -8,7 +8,6 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
|
|||
require Pleroma.Constants
|
||||
|
||||
alias Pleroma.Activity
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.HTML
|
||||
alias Pleroma.Maps
|
||||
alias Pleroma.Object
|
||||
|
|
@ -31,13 +30,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
|
|||
# pagination is restricted to 40 activities at a time
|
||||
defp fetch_rich_media_for_activities(activities) do
|
||||
Enum.each(activities, fn activity ->
|
||||
fun = fn -> Card.get_by_activity(activity) end
|
||||
|
||||
if Config.get([__MODULE__, :sync_fetching], false) do
|
||||
fun.()
|
||||
else
|
||||
spawn(fun)
|
||||
end
|
||||
Card.get_by_activity(activity)
|
||||
end)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -10,31 +10,21 @@ defmodule Pleroma.Web.RichMedia.Backfill do
|
|||
|
||||
require Logger
|
||||
|
||||
@backfiller Pleroma.Config.get([__MODULE__, :provider], Pleroma.Web.RichMedia.Backfill.Task)
|
||||
@cachex Pleroma.Config.get([:cachex, :provider], Cachex)
|
||||
@max_attempts 3
|
||||
@retry 5_000
|
||||
|
||||
def start(%{url: url} = args) when is_binary(url) do
|
||||
@spec run(map()) ::
|
||||
:ok | {:error, {:invalid_metadata, any()} | :body_too_large | {:content, any()} | any()}
|
||||
def run(%{"url" => url} = args) do
|
||||
url_hash = Card.url_to_hash(url)
|
||||
|
||||
args =
|
||||
args
|
||||
|> Map.put(:attempt, 1)
|
||||
|> Map.put(:url_hash, url_hash)
|
||||
|
||||
@backfiller.run(args)
|
||||
end
|
||||
|
||||
def run(%{url: url, url_hash: url_hash, attempt: attempt} = args)
|
||||
when attempt <= @max_attempts do
|
||||
case Parser.parse(url) do
|
||||
{:ok, fields} ->
|
||||
{:ok, card} = Card.create(url, fields)
|
||||
|
||||
maybe_schedule_expiration(url, fields)
|
||||
|
||||
if Map.has_key?(args, :activity_id) do
|
||||
with %{"activity_id" => activity_id} <- args,
|
||||
false <- is_nil(activity_id) do
|
||||
stream_update(args)
|
||||
end
|
||||
|
||||
|
|
@ -54,19 +44,10 @@ defmodule Pleroma.Web.RichMedia.Backfill do
|
|||
|
||||
e ->
|
||||
Logger.debug("Rich media error for #{url}: #{inspect(e)}")
|
||||
|
||||
:timer.sleep(@retry * attempt)
|
||||
|
||||
run(%{args | attempt: attempt + 1})
|
||||
{:error, e}
|
||||
end
|
||||
end
|
||||
|
||||
def run(%{url: url, url_hash: url_hash}) do
|
||||
Logger.debug("Rich media failure for #{url}")
|
||||
|
||||
negative_cache(url_hash, :timer.minutes(15))
|
||||
end
|
||||
|
||||
defp maybe_schedule_expiration(url, fields) do
|
||||
case TTL.process(fields, url) do
|
||||
{:ok, ttl} when is_number(ttl) ->
|
||||
|
|
@ -80,22 +61,14 @@ defmodule Pleroma.Web.RichMedia.Backfill do
|
|||
end
|
||||
end
|
||||
|
||||
defp stream_update(%{activity_id: activity_id}) do
|
||||
defp stream_update(%{"activity_id" => activity_id}) do
|
||||
Pleroma.Activity.get_by_id(activity_id)
|
||||
|> Pleroma.Activity.normalize()
|
||||
|> Pleroma.Web.ActivityPub.ActivityPub.stream_out()
|
||||
end
|
||||
|
||||
defp warm_cache(key, val), do: @cachex.put(:rich_media_cache, key, val)
|
||||
defp negative_cache(key, ttl \\ nil), do: @cachex.put(:rich_media_cache, key, nil, ttl: ttl)
|
||||
end
|
||||
|
||||
defmodule Pleroma.Web.RichMedia.Backfill.Task do
|
||||
alias Pleroma.Web.RichMedia.Backfill
|
||||
|
||||
def run(args) do
|
||||
Task.Supervisor.start_child(Pleroma.TaskSupervisor, Backfill, :run, [args],
|
||||
name: {:global, {:rich_media, args.url_hash}}
|
||||
)
|
||||
end
|
||||
defp negative_cache(key, ttl \\ :timer.minutes(15)),
|
||||
do: @cachex.put(:rich_media_cache, key, nil, ttl: ttl)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ defmodule Pleroma.Web.RichMedia.Card do
|
|||
alias Pleroma.HTML
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.Web.RichMedia.Backfill
|
||||
alias Pleroma.Web.RichMedia.Parser
|
||||
alias Pleroma.Workers.RichMediaWorker
|
||||
|
||||
@cachex Pleroma.Config.get([:cachex, :provider], Cachex)
|
||||
@config_impl Application.compile_env(:pleroma, [__MODULE__, :config_impl], Pleroma.Config)
|
||||
|
|
@ -75,17 +75,18 @@ defmodule Pleroma.Web.RichMedia.Card do
|
|||
|
||||
def get_by_url(nil), do: nil
|
||||
|
||||
@spec get_or_backfill_by_url(String.t(), map()) :: t() | nil
|
||||
def get_or_backfill_by_url(url, backfill_opts \\ %{}) do
|
||||
@spec get_or_backfill_by_url(String.t(), keyword()) :: t() | nil
|
||||
def get_or_backfill_by_url(url, opts \\ []) do
|
||||
if @config_impl.get([:rich_media, :enabled]) do
|
||||
case get_by_url(url) do
|
||||
%__MODULE__{} = card ->
|
||||
card
|
||||
|
||||
nil ->
|
||||
backfill_opts = Map.put(backfill_opts, :url, url)
|
||||
activity_id = Keyword.get(opts, :activity, nil)
|
||||
|
||||
Backfill.start(backfill_opts)
|
||||
RichMediaWorker.new(%{"op" => "backfill", "url" => url, "activity_id" => activity_id})
|
||||
|> Oban.insert()
|
||||
|
||||
nil
|
||||
|
||||
|
|
@ -137,7 +138,7 @@ defmodule Pleroma.Web.RichMedia.Card do
|
|||
nil
|
||||
else
|
||||
{:cached, url} ->
|
||||
get_or_backfill_by_url(url, %{activity_id: activity.id})
|
||||
get_or_backfill_by_url(url, activity_id: activity.id)
|
||||
|
||||
_ ->
|
||||
:error
|
||||
|
|
|
|||
|
|
@ -3,13 +3,17 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Workers.RichMediaWorker do
|
||||
alias Pleroma.Web.RichMedia.Backfill
|
||||
alias Pleroma.Web.RichMedia.Card
|
||||
|
||||
use Oban.Worker,
|
||||
queue: :background
|
||||
use Oban.Worker, queue: :background, max_attempts: 3, unique: [period: 300]
|
||||
|
||||
@impl Oban.Worker
|
||||
def perform(%Job{args: %{"op" => "expire", "url" => url} = _args}) do
|
||||
Card.delete(url)
|
||||
end
|
||||
|
||||
def perform(%Job{args: %{"op" => "backfill", "url" => _url} = args}) do
|
||||
Backfill.run(args)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue