diff --git a/changelog.d/user-refresh.change b/changelog.d/user-refresh.change new file mode 100644 index 000000000..b91169a9e --- /dev/null +++ b/changelog.d/user-refresh.change @@ -0,0 +1 @@ +User profile refreshes are now asynchronous diff --git a/config/test.exs b/config/test.exs index 0d4c82e0e..8cd3b0216 100644 --- a/config/test.exs +++ b/config/test.exs @@ -183,6 +183,8 @@ config :pleroma, Pleroma.Web.RichMedia.Backfill, provider: Pleroma.Web.RichMedia.Backfill +config :pleroma, Pleroma.User, sync_refreshing: true + if File.exists?("./config/test.secret.exs") do import_config "test.secret.exs" else diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 884c1f302..440dc9210 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -2154,20 +2154,23 @@ def html_filter_policy(_), do: Config.get([:markup, :scrub_policy]) def fetch_by_ap_id(ap_id), do: ActivityPub.make_user_from_ap_id(ap_id) + @spec get_or_fetch_by_ap_id(String.t()) :: {:ok, User.t()} | {:error, any()} def get_or_fetch_by_ap_id(ap_id) do - cached_user = get_cached_by_ap_id(ap_id) + with cached_user = %User{} <- get_cached_by_ap_id(ap_id), + _ <- maybe_refresh(cached_user) do + {:ok, cached_user} + else + _ -> fetch_by_ap_id(ap_id) + end + end - maybe_fetched_user = needs_update?(cached_user) && fetch_by_ap_id(ap_id) + defp maybe_refresh(user) do + fun = fn -> needs_update?(user) && fetch_by_ap_id(user.ap_id) end - case {cached_user, maybe_fetched_user} do - {_, {:ok, %User{} = user}} -> - {:ok, user} - - {%User{} = user, _} -> - {:ok, user} - - _ -> - {:error, :not_found} + if Config.get([__MODULE__, :sync_refreshing], false) do + fun.() + else + Task.start(fun) end end diff --git a/test/pleroma/user_test.exs b/test/pleroma/user_test.exs index 5b7a65658..0da9969d0 100644 --- a/test/pleroma/user_test.exs +++ b/test/pleroma/user_test.exs @@ -953,9 +953,12 @@ test "updates an existing user, if stale" do {:ok, user} = User.get_or_fetch_by_ap_id("http://mastodon.example.org/users/admin") - assert user.inbox + # User was updated async, fetch from cache now + updated_user = User.get_cached_by_ap_id(user.ap_id) - refute user.last_refreshed_at == orig_user.last_refreshed_at + assert updated_user.inbox + + refute updated_user.last_refreshed_at == orig_user.last_refreshed_at end test "if nicknames clash, the old user gets a prefix with the old id to the nickname" do