forked from AkkomaGang/akkoma
[#1335] User AP ID relations fetching performance optimizations.
This commit is contained in:
parent
565f261338
commit
555edd01ab
4 changed files with 70 additions and 20 deletions
|
@ -21,6 +21,8 @@ defmodule Pleroma.Notification do
|
||||||
|
|
||||||
@type t :: %__MODULE__{}
|
@type t :: %__MODULE__{}
|
||||||
|
|
||||||
|
@include_muted_option :with_muted
|
||||||
|
|
||||||
schema "notifications" do
|
schema "notifications" do
|
||||||
field(:seen, :boolean, default: false)
|
field(:seen, :boolean, default: false)
|
||||||
belongs_to(:user, User, type: FlakeId.Ecto.CompatType)
|
belongs_to(:user, User, type: FlakeId.Ecto.CompatType)
|
||||||
|
@ -34,7 +36,25 @@ def changeset(%Notification{} = notification, attrs) do
|
||||||
|> cast(attrs, [:seen])
|
|> cast(attrs, [:seen])
|
||||||
end
|
end
|
||||||
|
|
||||||
def for_user_query(user, opts \\ []) do
|
defp for_user_query_ap_id_opts(user, opts) do
|
||||||
|
ap_id_relations =
|
||||||
|
[:block] ++
|
||||||
|
if opts[@include_muted_option], do: [], else: [:notification_mute]
|
||||||
|
|
||||||
|
preloaded_ap_ids = User.outgoing_relations_ap_ids(user, ap_id_relations)
|
||||||
|
|
||||||
|
exclude_blocked_opts = Map.merge(%{blocked_users_ap_ids: preloaded_ap_ids[:block]}, opts)
|
||||||
|
|
||||||
|
exclude_notification_muted_opts =
|
||||||
|
Map.merge(%{notification_muted_users_ap_ids: preloaded_ap_ids[:notification_mute]}, opts)
|
||||||
|
|
||||||
|
{exclude_blocked_opts, exclude_notification_muted_opts}
|
||||||
|
end
|
||||||
|
|
||||||
|
def for_user_query(user, opts \\ %{}) do
|
||||||
|
{exclude_blocked_opts, exclude_notification_muted_opts} =
|
||||||
|
for_user_query_ap_id_opts(user, opts)
|
||||||
|
|
||||||
Notification
|
Notification
|
||||||
|> where(user_id: ^user.id)
|
|> where(user_id: ^user.id)
|
||||||
|> where(
|
|> where(
|
||||||
|
@ -54,13 +74,13 @@ def for_user_query(user, opts \\ []) do
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|> preload([n, a, o], activity: {a, object: o})
|
|> preload([n, a, o], activity: {a, object: o})
|
||||||
|> exclude_muted(user, opts)
|
|> exclude_notification_muted(user, exclude_notification_muted_opts)
|
||||||
|> exclude_blocked(user)
|
|> exclude_blocked(user, exclude_blocked_opts)
|
||||||
|> exclude_visibility(opts)
|
|> exclude_visibility(opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp exclude_blocked(query, user) do
|
defp exclude_blocked(query, user, opts) do
|
||||||
blocked_ap_ids = User.blocked_users_ap_ids(user)
|
blocked_ap_ids = opts[:blocked_users_ap_ids] || User.blocked_users_ap_ids(user)
|
||||||
|
|
||||||
query
|
query
|
||||||
|> where([n, a], a.actor not in ^blocked_ap_ids)
|
|> where([n, a], a.actor not in ^blocked_ap_ids)
|
||||||
|
@ -70,12 +90,13 @@ defp exclude_blocked(query, user) do
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp exclude_muted(query, _, %{with_muted: true}) do
|
defp exclude_notification_muted(query, _, %{@include_muted_option => true}) do
|
||||||
query
|
query
|
||||||
end
|
end
|
||||||
|
|
||||||
defp exclude_muted(query, user, _opts) do
|
defp exclude_notification_muted(query, user, opts) do
|
||||||
notification_muted_ap_ids = User.notification_muted_users_ap_ids(user)
|
notification_muted_ap_ids =
|
||||||
|
opts[:notification_muted_users_ap_ids] || User.notification_muted_users_ap_ids(user)
|
||||||
|
|
||||||
query
|
query
|
||||||
|> where([n, a], a.actor not in ^notification_muted_ap_ids)
|
|> where([n, a], a.actor not in ^notification_muted_ap_ids)
|
||||||
|
|
|
@ -1158,11 +1158,14 @@ def subscribed_to?(user, %{ap_id: ap_id}) do
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Returns map of related AP IDs list by relation type.
|
Returns map of outgoing (blocked, muted etc.) relations' user AP IDs by relation type.
|
||||||
E.g. `related_ap_ids(user, [:block])` -> `%{block: ["https://some.site/users/userapid"]}`
|
E.g. `outgoing_relations_ap_ids(user, [:block])` -> `%{block: ["https://some.site/users/userapid"]}`
|
||||||
"""
|
"""
|
||||||
@spec related_ap_ids(User.t(), list(atom())) :: %{atom() => list(String.t())}
|
@spec outgoing_relations_ap_ids(User.t(), list(atom())) :: %{atom() => list(String.t())}
|
||||||
def related_ap_ids(%User{} = user, relationship_types) when is_list(relationship_types) do
|
def outgoing_relations_ap_ids(_, []), do: %{}
|
||||||
|
|
||||||
|
def outgoing_relations_ap_ids(%User{} = user, relationship_types)
|
||||||
|
when is_list(relationship_types) do
|
||||||
db_result =
|
db_result =
|
||||||
user
|
user
|
||||||
|> assoc(:outgoing_relationships)
|
|> assoc(:outgoing_relationships)
|
||||||
|
|
|
@ -884,7 +884,7 @@ defp restrict_reblogs(query, _), do: query
|
||||||
defp restrict_muted(query, %{"with_muted" => val}) when val in [true, "true", "1"], do: query
|
defp restrict_muted(query, %{"with_muted" => val}) when val in [true, "true", "1"], do: query
|
||||||
|
|
||||||
defp restrict_muted(query, %{"muting_user" => %User{} = user} = opts) do
|
defp restrict_muted(query, %{"muting_user" => %User{} = user} = opts) do
|
||||||
mutes = opts["muted_ap_ids"] || User.muted_users_ap_ids(user)
|
mutes = opts["muted_users_ap_ids"] || User.muted_users_ap_ids(user)
|
||||||
|
|
||||||
query =
|
query =
|
||||||
from([activity] in query,
|
from([activity] in query,
|
||||||
|
@ -902,7 +902,7 @@ defp restrict_muted(query, %{"muting_user" => %User{} = user} = opts) do
|
||||||
defp restrict_muted(query, _), do: query
|
defp restrict_muted(query, _), do: query
|
||||||
|
|
||||||
defp restrict_blocked(query, %{"blocking_user" => %User{} = user} = opts) do
|
defp restrict_blocked(query, %{"blocking_user" => %User{} = user} = opts) do
|
||||||
blocked_ap_ids = opts["blocked_ap_ids"] || User.blocked_users_ap_ids(user)
|
blocked_ap_ids = opts["blocked_users_ap_ids"] || User.blocked_users_ap_ids(user)
|
||||||
domain_blocks = user.domain_blocks || []
|
domain_blocks = user.domain_blocks || []
|
||||||
|
|
||||||
query =
|
query =
|
||||||
|
@ -944,8 +944,8 @@ defp restrict_pinned(query, %{"pinned" => "true", "pinned_activity_ids" => ids})
|
||||||
|
|
||||||
defp restrict_pinned(query, _), do: query
|
defp restrict_pinned(query, _), do: query
|
||||||
|
|
||||||
defp restrict_muted_reblogs(query, %{"muting_user" => %User{} = user}) do
|
defp restrict_muted_reblogs(query, %{"muting_user" => %User{} = user} = opts) do
|
||||||
muted_reblogs = User.reblog_muted_users_ap_ids(user)
|
muted_reblogs = opts["reblog_muted_users_ap_ids"] || User.reblog_muted_users_ap_ids(user)
|
||||||
|
|
||||||
from(
|
from(
|
||||||
activity in query,
|
activity in query,
|
||||||
|
@ -1012,7 +1012,33 @@ defp maybe_order(query, %{order: :asc}) do
|
||||||
|
|
||||||
defp maybe_order(query, _), do: query
|
defp maybe_order(query, _), do: query
|
||||||
|
|
||||||
|
defp fetch_activities_query_ap_ids_ops(opts) do
|
||||||
|
source_user = opts["muting_user"]
|
||||||
|
ap_id_relations = if source_user, do: [:mute, :reblog_mute], else: []
|
||||||
|
|
||||||
|
ap_id_relations =
|
||||||
|
ap_id_relations ++
|
||||||
|
if opts["blocking_user"] && opts["blocking_user"] == source_user do
|
||||||
|
[:block]
|
||||||
|
else
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
|
||||||
|
preloaded_ap_ids = User.outgoing_relations_ap_ids(source_user, ap_id_relations)
|
||||||
|
|
||||||
|
restrict_blocked_opts = Map.merge(%{"blocked_users_ap_ids" => preloaded_ap_ids[:block]}, opts)
|
||||||
|
restrict_muted_opts = Map.merge(%{"muted_users_ap_ids" => preloaded_ap_ids[:mute]}, opts)
|
||||||
|
|
||||||
|
restrict_muted_reblogs_opts =
|
||||||
|
Map.merge(%{"reblog_muted_users_ap_ids" => preloaded_ap_ids[:reblog_mute]}, opts)
|
||||||
|
|
||||||
|
{restrict_blocked_opts, restrict_muted_opts, restrict_muted_reblogs_opts}
|
||||||
|
end
|
||||||
|
|
||||||
def fetch_activities_query(recipients, opts \\ %{}) do
|
def fetch_activities_query(recipients, opts \\ %{}) do
|
||||||
|
{restrict_blocked_opts, restrict_muted_opts, restrict_muted_reblogs_opts} =
|
||||||
|
fetch_activities_query_ap_ids_ops(opts)
|
||||||
|
|
||||||
config = %{
|
config = %{
|
||||||
skip_thread_containment: Config.get([:instance, :skip_thread_containment])
|
skip_thread_containment: Config.get([:instance, :skip_thread_containment])
|
||||||
}
|
}
|
||||||
|
@ -1032,15 +1058,15 @@ def fetch_activities_query(recipients, opts \\ %{}) do
|
||||||
|> restrict_type(opts)
|
|> restrict_type(opts)
|
||||||
|> restrict_state(opts)
|
|> restrict_state(opts)
|
||||||
|> restrict_favorited_by(opts)
|
|> restrict_favorited_by(opts)
|
||||||
|> restrict_blocked(opts)
|
|> restrict_blocked(restrict_blocked_opts)
|
||||||
|> restrict_muted(opts)
|
|> restrict_muted(restrict_muted_opts)
|
||||||
|> restrict_media(opts)
|
|> restrict_media(opts)
|
||||||
|> restrict_visibility(opts)
|
|> restrict_visibility(opts)
|
||||||
|> restrict_thread_visibility(opts, config)
|
|> restrict_thread_visibility(opts, config)
|
||||||
|> restrict_replies(opts)
|
|> restrict_replies(opts)
|
||||||
|> restrict_reblogs(opts)
|
|> restrict_reblogs(opts)
|
||||||
|> restrict_pinned(opts)
|
|> restrict_pinned(opts)
|
||||||
|> restrict_muted_reblogs(opts)
|
|> restrict_muted_reblogs(restrict_muted_reblogs_opts)
|
||||||
|> Activity.restrict_deactivated_users()
|
|> Activity.restrict_deactivated_users()
|
||||||
|> exclude_poll_votes(opts)
|
|> exclude_poll_votes(opts)
|
||||||
|> exclude_visibility(opts)
|
|> exclude_visibility(opts)
|
||||||
|
|
|
@ -130,7 +130,7 @@ defp do_stream(%{topic: topic, item: item}) do
|
||||||
|
|
||||||
defp should_send?(%User{} = user, %Activity{} = item) do
|
defp should_send?(%User{} = user, %Activity{} = item) do
|
||||||
%{block: blocked_ap_ids, mute: muted_ap_ids, reblog_mute: reblog_muted_ap_ids} =
|
%{block: blocked_ap_ids, mute: muted_ap_ids, reblog_mute: reblog_muted_ap_ids} =
|
||||||
User.related_ap_ids(user, [:block, :mute, :reblog_mute])
|
User.outgoing_relations_ap_ids(user, [:block, :mute, :reblog_mute])
|
||||||
|
|
||||||
recipient_blocks = MapSet.new(blocked_ap_ids ++ muted_ap_ids)
|
recipient_blocks = MapSet.new(blocked_ap_ids ++ muted_ap_ids)
|
||||||
recipients = MapSet.new(item.recipients)
|
recipients = MapSet.new(item.recipients)
|
||||||
|
|
Loading…
Reference in a new issue