Use atomic update for note count and follower count

This commit is contained in:
eugenijm 2019-03-03 17:27:09 +03:00
parent 9b63fda9c7
commit af0039a3a0
1 changed files with 56 additions and 31 deletions

View File

@ -662,23 +662,43 @@ def get_follow_requests(%User{} = 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
@ -702,24 +722,29 @@ def update_note_count(%User{} = 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