Diagnostics tasks (#348)
authorfloatingghost <hannah@coffee-and-dreams.uk>
Wed, 7 Dec 2022 11:12:34 +0000 (11:12 +0000)
committerfloatingghost <hannah@coffee-and-dreams.uk>
Wed, 7 Dec 2022 11:12:34 +0000 (11:12 +0000)
a bunch of ways to get query plans to help with debugging

Co-authored-by: FloatingGhost <hannah@coffee-and-dreams.uk>
Reviewed-on: https://akkoma.dev/AkkomaGang/akkoma/pulls/348

docs/docs/administration/CLI_tasks/diagnostics.md [new file with mode: 0644]
lib/mix/tasks/pleroma/diagnostics.ex [new file with mode: 0644]
lib/pleroma/web/activity_pub/activity_pub.ex

diff --git a/docs/docs/administration/CLI_tasks/diagnostics.md b/docs/docs/administration/CLI_tasks/diagnostics.md
new file mode 100644 (file)
index 0000000..25572da
--- /dev/null
@@ -0,0 +1,30 @@
+# Diagnostics
+
+A few tasks to help with debugging, troubleshooting, and diagnosing problems.
+
+They mostly relate to common postgres queries. 
+
+## Home timeline query plan
+
+This task will print a query plan for the home timeline of a given user.
+
+=== "OTP"
+
+    `./bin/pleroma_ctl diagnostics home_timeline <nickname>`
+
+=== "From Source"
+
+    `mix pleroma.diagnostics home_timeline <nickname>`
+
+## User timeline query plan
+
+This task will print a query plan for the user timeline of a given user,
+from the perspective of another given user.
+
+=== "OTP"
+
+    `./bin/pleroma_ctl diagnostics user_timeline <nickname> <viewing_nickname>`
+
+=== "From Source"
+    
+    `mix pleroma.diagnostics user_timeline <nickname> <viewing_nickname>`
\ No newline at end of file
diff --git a/lib/mix/tasks/pleroma/diagnostics.ex b/lib/mix/tasks/pleroma/diagnostics.ex
new file mode 100644 (file)
index 0000000..6e83bf6
--- /dev/null
@@ -0,0 +1,77 @@
+defmodule Mix.Tasks.Pleroma.Diagnostics do
+  alias Pleroma.Repo
+  alias Pleroma.User
+
+  require Logger
+  require Pleroma.Constants
+
+  import Mix.Pleroma
+  import Ecto.Query
+  use Mix.Task
+
+  def run(["home_timeline", nickname]) do
+    start_pleroma()
+    user = Repo.get_by!(User, nickname: nickname)
+    Logger.info("Home timeline query #{user.nickname}")
+
+    followed_hashtags =
+      user
+      |> User.followed_hashtags()
+      |> Enum.map(& &1.id)
+
+    params =
+      %{limit: 20}
+      |> Map.put(:type, ["Create", "Announce"])
+      |> Map.put(:blocking_user, user)
+      |> Map.put(:muting_user, user)
+      |> Map.put(:reply_filtering_user, user)
+      |> Map.put(:announce_filtering_user, user)
+      |> Map.put(:user, user)
+      |> Map.put(:followed_hashtags, followed_hashtags)
+      |> Map.delete(:local)
+
+    list_memberships = Pleroma.List.memberships(user)
+    recipients = [user.ap_id | User.following(user)]
+
+    query =
+      Pleroma.Web.ActivityPub.ActivityPub.fetch_activities_query(
+        recipients ++ list_memberships,
+        params
+      )
+      |> limit(20)
+
+    Ecto.Adapters.SQL.explain(Repo, :all, query, analyze: true, timeout: :infinity)
+    |> IO.puts()
+  end
+
+  def run(["user_timeline", nickname, reading_nickname]) do
+    start_pleroma()
+    user = Repo.get_by!(User, nickname: nickname)
+    reading_user = Repo.get_by!(User, nickname: reading_nickname)
+    Logger.info("User timeline query #{user.nickname}")
+
+    params =
+      %{limit: 20}
+      |> Map.put(:type, ["Create", "Announce"])
+      |> Map.put(:user, reading_user)
+      |> Map.put(:actor_id, user.ap_id)
+      |> Map.put(:pinned_object_ids, Map.keys(user.pinned_objects))
+
+    list_memberships = Pleroma.List.memberships(user)
+
+    recipients =
+      %{
+        godmode: params[:godmode],
+        reading_user: reading_user
+      }
+      |> Pleroma.Web.ActivityPub.ActivityPub.user_activities_recipients()
+
+    query =
+      (recipients ++ list_memberships)
+      |> Pleroma.Web.ActivityPub.ActivityPub.fetch_activities_query(params)
+      |> limit(20)
+
+    Ecto.Adapters.SQL.explain(Repo, :all, query, analyze: true, timeout: :infinity)
+    |> IO.puts()
+  end
+end
index 3f46a8ecb18d6f35c2785f268311b69dff153457..d700128c07a7067c245d6c9a208188b4c2b42c20 100644 (file)
@@ -739,9 +739,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
     |> fetch_activities(params, :offset)
   end
 
-  defp user_activities_recipients(%{godmode: true}), do: []
+  def user_activities_recipients(%{godmode: true}), do: []
 
-  defp user_activities_recipients(%{reading_user: reading_user}) do
+  def user_activities_recipients(%{reading_user: reading_user}) do
     if not is_nil(reading_user) and reading_user.local do
       [
         Constants.as_public(),