Merge branch 'atomic-note-count-updates' into 'develop'

Atomic update for note count and follower count

See merge request pleroma/pleroma!885
This commit is contained in:
kaniini 2019-03-03 15:50:41 +00:00
commit 413cf00cc3
1 changed files with 56 additions and 31 deletions

View File

@ -636,23 +636,43 @@ defmodule Pleroma.User do
end end
def increase_note_count(%User{} = user) do def increase_note_count(%User{} = user) do
info_cng = User.Info.add_to_note_count(user.info, 1) User
|> where(id: ^user.id)
cng = |> update([u],
change(user) set: [
|> put_embed(:info, info_cng) info:
fragment(
update_and_set_cache(cng) "jsonb_set(?, '{note_count}', ((?->>'note_count')::int + 1)::varchar::jsonb, true)",
u.info,
u.info
)
]
)
|> Repo.update_all([], returning: true)
|> case do
{1, [user]} -> set_cache(user)
_ -> {:error, user}
end
end end
def decrease_note_count(%User{} = user) do def decrease_note_count(%User{} = user) do
info_cng = User.Info.add_to_note_count(user.info, -1) User
|> where(id: ^user.id)
cng = |> update([u],
change(user) set: [
|> put_embed(:info, info_cng) info:
fragment(
update_and_set_cache(cng) "jsonb_set(?, '{note_count}', (greatest(0, (?->>'note_count')::int - 1))::varchar::jsonb, true)",
u.info,
u.info
)
]
)
|> Repo.update_all([], returning: true)
|> case do
{1, [user]} -> set_cache(user)
_ -> {:error, user}
end
end end
def update_note_count(%User{} = user) do def update_note_count(%User{} = user) do
@ -676,24 +696,29 @@ defmodule Pleroma.User do
def update_follower_count(%User{} = user) do def update_follower_count(%User{} = user) do
follower_count_query = follower_count_query =
from( User
u in User, |> where([u], ^user.follower_address in u.following)
where: ^user.follower_address in u.following, |> where([u], u.id != ^user.id)
where: u.id != ^user.id, |> select([u], %{count: count(u.id)})
select: count(u.id)
)
follower_count = Repo.one(follower_count_query) User
|> where(id: ^user.id)
info_cng = |> join(:inner, [u], s in subquery(follower_count_query))
user.info |> update([u, s],
|> User.Info.set_follower_count(follower_count) set: [
info:
cng = fragment(
change(user) "jsonb_set(?, '{follower_count}', ?::varchar::jsonb, true)",
|> put_embed(:info, info_cng) u.info,
s.count
update_and_set_cache(cng) )
]
)
|> Repo.update_all([], returning: true)
|> case do
{1, [user]} -> set_cache(user)
_ -> {:error, user}
end
end end
def get_users_from_set_query(ap_ids, false) do def get_users_from_set_query(ap_ids, false) do