diff --git a/changelog.d/stats-peers-from-instances.change b/changelog.d/stats-peers-from-instances.change index c493b4550..a3dfe2e0c 100644 --- a/changelog.d/stats-peers-from-instances.change +++ b/changelog.d/stats-peers-from-instances.change @@ -1 +1 @@ -Read the peer list from the instances table and update instance stats every 5 minutes instead of every minute; the old peers query was one of the most expensive regular queries +Read the peer list from the instances table (hosts of remote actors, without our own host) and update instance stats every 5 minutes; the old peers query scanned all remote users every minute diff --git a/lib/pleroma/stats.ex b/lib/pleroma/stats.ex index 328aa110a..079f6f7dd 100644 --- a/lib/pleroma/stats.ex +++ b/lib/pleroma/stats.ex @@ -67,7 +67,10 @@ defmodule Pleroma.Stats do def calculate_stat_data do # Hosts are unique in instances, and remote users add theirs. Scanning # all remote users for their domains was one of the costliest queries. - peers = Repo.all(from(i in Instance, select: i.host)) + # Favicon lookups for local accounts can add our own host, so skip it. + peers = + from(i in Instance, where: i.host != ^local_host(), select: i.host) + |> Repo.all() domain_count = Enum.count(peers) @@ -93,6 +96,9 @@ defmodule Pleroma.Stats do } end + # Read from the config: this also runs before the endpoint has started. + defp local_host, do: Pleroma.Config.get([Pleroma.Web.Endpoint, :url, :host]) + @spec get_status_visibility_count(String.t() | nil) :: map() def get_status_visibility_count(instance \\ nil) do if is_nil(instance) do diff --git a/priv/repo/migrations/20261028000000_backfill_instances_from_users.exs b/priv/repo/migrations/20261028000000_backfill_instances_from_users.exs index 13d805c30..88dfe9ec5 100644 --- a/priv/repo/migrations/20261028000000_backfill_instances_from_users.exs +++ b/priv/repo/migrations/20261028000000_backfill_instances_from_users.exs @@ -13,7 +13,8 @@ defmodule Pleroma.Repo.Migrations.BackfillInstancesFromUsers do INSERT INTO instances (host, inserted_at, updated_at) SELECT DISTINCT host, now(), now() FROM ( - SELECT substring(ap_id from '^[A-Za-z][A-Za-z0-9+.-]*://([^/:?#]+)') AS host + -- Skips userinfo; IPv6 literals give NULL and are left out. + SELECT substring(ap_id from '^[A-Za-z][A-Za-z0-9+.-]*://(?:[^/?#@]*@)?([^/:?#\\[]+)') AS host FROM users WHERE local = false AND ap_id IS NOT NULL ) AS hosts diff --git a/test/pleroma/repo/migrations/backfill_instances_from_users_test.exs b/test/pleroma/repo/migrations/backfill_instances_from_users_test.exs index 733c6644b..811e336bd 100644 --- a/test/pleroma/repo/migrations/backfill_instances_from_users_test.exs +++ b/test/pleroma/repo/migrations/backfill_instances_from_users_test.exs @@ -19,12 +19,14 @@ defmodule Pleroma.Repo.Migrations.BackfillInstancesFromUsersTest do insert(:user, local: false, ap_id: "https://new.example/users/a") insert(:user, local: false, ap_id: "https://new.example/users/b") insert(:user, local: false, ap_id: "https://ported.example:8443/users/c") + insert(:user, local: false, ap_id: "https://user@userinfo.example/users/d") + insert(:user, local: false, ap_id: "https://[2001:db8::1]/users/e") insert(:user, local: true) migration.up() hosts = Instance |> Repo.all() |> Enum.map(& &1.host) |> Enum.sort() - assert hosts == ["known.example", "new.example", "ported.example"] + assert hosts == ["known.example", "new.example", "ported.example", "userinfo.example"] assert %{unreachable_since: ^unreachable_since} = Repo.get_by(Instance, host: "known.example") end diff --git a/test/pleroma/web/mastodon_api/controllers/instance_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/instance_controller_test.exs index 404d276db..f9d42d981 100644 --- a/test/pleroma/web/mastodon_api/controllers/instance_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/instance_controller_test.exs @@ -86,6 +86,8 @@ defmodule Pleroma.Web.MastodonAPI.InstanceControllerTest do # Peers come from the instances table, which remote users add to. insert(:instance, host: "peer1.com") insert(:instance, host: "peer2.com") + # Favicon lookups for local accounts can add our own host. + insert(:instance, host: Pleroma.Web.Endpoint.host()) Pleroma.Stats.force_update()