From 4100b2f9625094d01e53f3ed46529a5501f969d7 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Wed, 12 May 2021 18:18:20 +0200 Subject: [PATCH] Refresh profiles in a background task Signed-off-by: Thomas Citharel --- lib/federation/activity_pub/refresher.ex | 5 ++-- lib/federation/activity_pub/relay.ex | 10 +++++--- lib/federation/activity_pub/transmogrifier.ex | 7 ++++-- lib/graphql/resolvers/actor.ex | 24 +++++++++++++------ lib/mix/tasks/mobilizon/relay/refresh.ex | 2 +- lib/service/workers/background.ex | 7 ++++++ 6 files changed, 40 insertions(+), 15 deletions(-) diff --git a/lib/federation/activity_pub/refresher.ex b/lib/federation/activity_pub/refresher.ex index 8c466838c..57399a69a 100644 --- a/lib/federation/activity_pub/refresher.ex +++ b/lib/federation/activity_pub/refresher.ex @@ -32,9 +32,10 @@ defmodule Mobilizon.Federation.ActivityPub.Refresher do end def refresh_profile(%Actor{type: type, url: url}) when type in [:Person, :Application] do - with {:ok, %Actor{outbox_url: outbox_url}} <- ActivityPubActor.make_actor_from_url(url), + with {:ok, %Actor{outbox_url: outbox_url} = actor} <- + ActivityPubActor.make_actor_from_url(url), :ok <- fetch_collection(outbox_url, Relay.get_actor()) do - :ok + {:ok, actor} end end diff --git a/lib/federation/activity_pub/relay.ex b/lib/federation/activity_pub/relay.ex index 8266d94f5..90eb4cea2 100644 --- a/lib/federation/activity_pub/relay.ex +++ b/lib/federation/activity_pub/relay.ex @@ -12,9 +12,10 @@ defmodule Mobilizon.Federation.ActivityPub.Relay do alias Mobilizon.Actors.{Actor, Follower} alias Mobilizon.Federation.ActivityPub - alias Mobilizon.Federation.ActivityPub.{Activity, Refresher, Transmogrifier} + alias Mobilizon.Federation.ActivityPub.{Activity, Transmogrifier} alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor alias Mobilizon.Federation.WebFinger + alias Mobilizon.Service.Workers.Background alias Mobilizon.GraphQL.API.Follows @@ -95,13 +96,16 @@ defmodule Mobilizon.Federation.ActivityPub.Relay do end end + @spec refresh(String.t()) :: {:ok, any()} def refresh(address) do Logger.debug("We're trying to refresh a remote instance") with {:ok, target_instance} <- fetch_actor(address), - {:ok, %Actor{} = target_actor} <- + {:ok, %Actor{id: target_actor_id}} <- ActivityPubActor.get_or_fetch_actor_by_url(target_instance) do - Refresher.refresh_profile(target_actor) + Background.enqueue("refresh_profile", %{ + "actor_id" => target_actor_id + }) end end diff --git a/lib/federation/activity_pub/transmogrifier.ex b/lib/federation/activity_pub/transmogrifier.ex index e527ac915..ea0509589 100644 --- a/lib/federation/activity_pub/transmogrifier.ex +++ b/lib/federation/activity_pub/transmogrifier.ex @@ -17,10 +17,11 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do alias Mobilizon.Todos.{Todo, TodoList} alias Mobilizon.Federation.ActivityPub - alias Mobilizon.Federation.ActivityPub.{Activity, Refresher, Relay, Utils} + alias Mobilizon.Federation.ActivityPub.{Activity, Relay, Utils} alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor alias Mobilizon.Federation.ActivityPub.Types.Ownable alias Mobilizon.Federation.ActivityStream.{Converter, Convertible} + alias Mobilizon.Service.Workers.Background alias Mobilizon.Tombstone alias Mobilizon.Web.Email.Participation alias Mobilizon.Web.Endpoint @@ -792,7 +793,9 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do # If this is an instance follow, refresh the followed profile (especially their outbox) if follower.id == relay_actor.id do - Refresher.refresh_profile(followed) + Background.enqueue("refresh_profile", %{ + "actor_id" => followed.id + }) end {:ok, activity, follow} diff --git a/lib/graphql/resolvers/actor.ex b/lib/graphql/resolvers/actor.ex index b67e9cacc..54e60293e 100644 --- a/lib/graphql/resolvers/actor.ex +++ b/lib/graphql/resolvers/actor.ex @@ -7,7 +7,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Actor do alias Mobilizon.{Actors, Admin, Users} alias Mobilizon.Actors.Actor alias Mobilizon.Federation.ActivityPub - alias Mobilizon.Federation.ActivityPub.Refresher + alias Mobilizon.Service.Workers.Background alias Mobilizon.Users.User import Mobilizon.Web.Gettext @@ -16,8 +16,11 @@ defmodule Mobilizon.GraphQL.Resolvers.Actor do def refresh_profile(_parent, %{id: id}, %{context: %{current_user: %User{role: role}}}) when is_admin(role) do case Actors.get_actor(id) do - %Actor{domain: domain} = actor when not is_nil(domain) -> - Refresher.refresh_profile(actor) + %Actor{domain: domain, id: actor_id} = actor when not is_nil(domain) -> + Background.enqueue("refresh_profile", %{ + "actor_id" => actor_id + }) + {:ok, actor} %Actor{} -> @@ -80,7 +83,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Actor do {:delete_tombstones, {_, nil}} <- {:delete_tombstones, Mobilizon.Tombstone.delete_actor_tombstones(id)}, {:ok, %Actor{} = actor} <- Actors.update_actor(actor, %{suspended: false}), - {:ok, %Actor{} = actor} <- refresh_if_remote(actor), + :ok <- refresh_if_remote(actor), {:ok, _} <- Admin.log_action(moderator_actor, "unsuspend", actor) do {:ok, actor} else @@ -99,7 +102,14 @@ defmodule Mobilizon.GraphQL.Resolvers.Actor do {:error, dgettext("errors", "Only moderators and administrators can unsuspend a profile")} end - @spec refresh_if_remote(Actor.t()) :: {:ok, Actor.t()} - defp refresh_if_remote(%Actor{domain: nil} = actor), do: {:ok, actor} - defp refresh_if_remote(%Actor{} = actor), do: Refresher.refresh_profile(actor) + @spec refresh_if_remote(Actor.t()) :: :ok + defp refresh_if_remote(%Actor{domain: nil}), do: :ok + + defp refresh_if_remote(%Actor{id: actor_id}) do + Background.enqueue("refresh_profile", %{ + "actor_id" => actor_id + }) + + :ok + end end diff --git a/lib/mix/tasks/mobilizon/relay/refresh.ex b/lib/mix/tasks/mobilizon/relay/refresh.ex index f788009b4..d598d7937 100644 --- a/lib/mix/tasks/mobilizon/relay/refresh.ex +++ b/lib/mix/tasks/mobilizon/relay/refresh.ex @@ -14,7 +14,7 @@ defmodule Mix.Tasks.Mobilizon.Relay.Refresh do IO.puts("Refreshing #{target}, this can take a while.") case Relay.refresh(target) do - :ok -> + {:ok, _} -> IO.puts("Refreshed #{target}") err -> diff --git a/lib/service/workers/background.ex b/lib/service/workers/background.ex index ad0f06055..a9e93504e 100644 --- a/lib/service/workers/background.ex +++ b/lib/service/workers/background.ex @@ -5,6 +5,7 @@ defmodule Mobilizon.Service.Workers.Background do alias Mobilizon.Actors alias Mobilizon.Actors.Actor + alias Mobilizon.Federation.ActivityPub.Refresher use Mobilizon.Service.Workers.Helper, queue: "background" @@ -22,4 +23,10 @@ defmodule Mobilizon.Service.Workers.Background do Actors.actor_key_rotation(actor) end end + + def perform(%Job{args: %{"op" => "refresh_profile", "actor_id" => actor_id}}) do + with %Actor{} = actor <- Actors.get_actor(actor_id) do + Refresher.refresh_profile(actor) + end + end end