diff options
author | Ivan Tashkinov <ivantashkinov@gmail.com> | 2019-01-23 18:37:25 +0300 |
---|---|---|
committer | Ivan Tashkinov <ivantashkinov@gmail.com> | 2019-01-23 18:37:25 +0300 |
commit | f161a92cb1abd981e37367fcd5d315ac14510d12 (patch) | |
tree | 3f39f536006e39f689226c4aa0d9a227251d5c2c /lib/pleroma/instances | |
parent | 4a278cd80a02fa1882db17397bb97b155c76570e (diff) | |
download | pleroma-f161a92cb1abd981e37367fcd5d315ac14510d12.tar.gz |
[#534] Initial implementation of unreachable federation targets retirement.
Diffstat (limited to 'lib/pleroma/instances')
-rw-r--r-- | lib/pleroma/instances/instance.ex | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/lib/pleroma/instances/instance.ex b/lib/pleroma/instances/instance.ex new file mode 100644 index 000000000..4507ef6d5 --- /dev/null +++ b/lib/pleroma/instances/instance.ex @@ -0,0 +1,77 @@ +defmodule Pleroma.Instances.Instance do + @moduledoc "Instance." + + alias Pleroma.Instances + alias Pleroma.Instances.Instance + + use Ecto.Schema + + import Ecto.{Query, Changeset} + + alias Pleroma.Repo + + schema "instances" do + field(:host, :string) + field(:unreachable_since, :naive_datetime) + field(:reachability_checked_at, :naive_datetime) + + timestamps() + end + + def update_changeset(struct, params \\ %{}) do + struct + |> cast(params, [:host, :unreachable_since, :reachability_checked_at]) + |> unique_constraint(:host) + end + + def reachable?(url) do + !Repo.one( + from(i in Instance, + where: + i.host == ^host(url) and i.unreachable_since <= ^Instances.reachability_time_threshold(), + select: true + ) + ) + end + + def set_reachable(url) do + Repo.update_all( + from(i in Instance, where: i.host == ^host(url)), + set: [ + unreachable_since: nil, + reachability_checked_at: DateTime.utc_now() + ] + ) + end + + def set_unreachable(url, unreachable_since \\ nil) do + unreachable_since = unreachable_since || DateTime.utc_now() + host = host(url) + existing_record = Repo.get_by(Instance, %{host: host}) + + changes = %{ + unreachable_since: unreachable_since, + reachability_checked_at: NaiveDateTime.utc_now() + } + + if existing_record do + update_changes = + if existing_record.unreachable_since && + NaiveDateTime.compare(existing_record.unreachable_since, unreachable_since) != :gt, + do: Map.delete(changes, :unreachable_since), + else: changes + + {:ok, _instance} = Repo.update(update_changeset(existing_record, update_changes)) + else + {:ok, _instance} = Repo.insert(update_changeset(%Instance{}, Map.put(changes, :host, host))) + end + end + + defp host(url_or_host) do + if url_or_host =~ ~r/^http/i do + URI.parse(url_or_host).host + else + url_or_host + end + end +end |