From 4dcbb64f19723334a9ef66b4ce71856d30e32796 Mon Sep 17 00:00:00 2001 From: Roger Braun Date: Tue, 31 Oct 2017 16:37:11 +0100 Subject: [PATCH] Avoid potentially slow count queries for user note count. For a variety of reasons, posgresql won't use the available actor, type index to do an index only scan. We now just increase the user note count, which will lead to slightly wrong counts in some cases, but it's better than the potentially very slow count query. --- lib/pleroma/user.ex | 9 +++++++++ lib/pleroma/web/common_api/common_api.ex | 2 +- lib/pleroma/web/ostatus/handlers/note_handler.ex | 2 +- test/user_test.exs | 15 +++++++++++++++ 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index bf63a22b3..5f1750035 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -239,6 +239,15 @@ def get_friends(%User{id: id, following: following}) do {:ok, Repo.all(q)} end + def increase_note_count(%User{} = user) do + note_count = (user.info["note_count"] || 0) + 1 + new_info = Map.put(user.info, "note_count", note_count) + + cs = info_changeset(user, %{info: new_info}) + + Repo.update(cs) + end + def update_note_count(%User{} = user) do note_count_query = from a in Object, where: fragment("?->>'actor' = ? and ?->>'type' = 'Note'", a.data, ^user.ap_id, a.data), diff --git a/lib/pleroma/web/common_api/common_api.ex b/lib/pleroma/web/common_api/common_api.ex index a865cd143..c9822dc2d 100644 --- a/lib/pleroma/web/common_api/common_api.ex +++ b/lib/pleroma/web/common_api/common_api.ex @@ -61,7 +61,7 @@ def post(user, %{"status" => status} = data) do context <- make_context(inReplyTo), object <- make_note_data(user.ap_id, to, context, content_html, attachments, inReplyTo, tags) do res = ActivityPub.create(to, user, context, object) - User.update_note_count(user) + User.increase_note_count(user) res end end diff --git a/lib/pleroma/web/ostatus/handlers/note_handler.ex b/lib/pleroma/web/ostatus/handlers/note_handler.ex index dda5c7d5e..b151c118a 100644 --- a/lib/pleroma/web/ostatus/handlers/note_handler.ex +++ b/lib/pleroma/web/ostatus/handlers/note_handler.ex @@ -112,7 +112,7 @@ def handle_note(entry, doc \\ nil) do note <- (if inReplyTo && !inReplyToActivity, do: note |> Map.put("inReplyTo", inReplyTo), else: note) do res = ActivityPub.create(to, actor, context, note, %{}, date, false) - User.update_note_count(actor) + User.increase_note_count(actor) res else %Activity{} = activity -> {:ok, activity} diff --git a/test/user_test.exs b/test/user_test.exs index 097d7d98e..ae9a48e74 100644 --- a/test/user_test.exs +++ b/test/user_test.exs @@ -246,6 +246,21 @@ test "it sets the info->note_count property" do assert user.info["note_count"] == 1 end + test "it increases the info->note_count property" do + note = insert(:note) + user = User.get_by_ap_id(note.data["actor"]) + + assert user.info["note_count"] == nil + + {:ok, user} = User.increase_note_count(user) + + assert user.info["note_count"] == 1 + + {:ok, user} = User.increase_note_count(user) + + assert user.info["note_count"] == 2 + end + test "it sets the info->follower_count property" do user = insert(:user) follower = insert(:user)