aboutsummaryrefslogtreecommitdiff
path: root/lib/pleroma/instances
diff options
context:
space:
mode:
authorIvan Tashkinov <ivantashkinov@gmail.com>2019-01-23 18:37:25 +0300
committerIvan Tashkinov <ivantashkinov@gmail.com>2019-01-23 18:37:25 +0300
commitf161a92cb1abd981e37367fcd5d315ac14510d12 (patch)
tree3f39f536006e39f689226c4aa0d9a227251d5c2c /lib/pleroma/instances
parent4a278cd80a02fa1882db17397bb97b155c76570e (diff)
downloadpleroma-f161a92cb1abd981e37367fcd5d315ac14510d12.tar.gz
[#534] Initial implementation of unreachable federation targets retirement.
Diffstat (limited to 'lib/pleroma/instances')
-rw-r--r--lib/pleroma/instances/instance.ex77
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