74 lines
1.9 KiB
Elixir
74 lines
1.9 KiB
Elixir
# Pleroma: A lightweight social networking server
|
|
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
|
# SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
defmodule Pleroma.Workers.PublisherWorker do
|
|
alias Pleroma.Activity
|
|
alias Pleroma.Config
|
|
alias Pleroma.Instances
|
|
alias Pleroma.Web.Federator
|
|
|
|
use Oban.Worker, queue: :federator_outgoing, max_attempts: 13
|
|
|
|
@publish_one_param_keys %{
|
|
"activity_id" => :activity_id,
|
|
"cc" => :cc,
|
|
"inbox" => :inbox,
|
|
"unreachable_since" => :unreachable_since
|
|
}
|
|
|
|
@impl true
|
|
def perform(%Job{args: %{"op" => "publish", "activity_id" => activity_id}}) do
|
|
activity = Activity.get_by_id(activity_id)
|
|
federator().perform(:publish, activity)
|
|
end
|
|
|
|
def perform(%Job{args: %{"op" => "publish_one", "params" => params}} = job) do
|
|
params =
|
|
Enum.reduce(params, %{}, fn {key, value}, acc ->
|
|
case @publish_one_param_keys do
|
|
%{^key => atom_key} -> Map.put(acc, atom_key, value)
|
|
_ -> acc
|
|
end
|
|
end)
|
|
|
|
# Cancel / skip the job if this server believed to be unreachable now
|
|
if not Instances.reachable?(params.inbox) do
|
|
{:cancel, :unreachable}
|
|
else
|
|
case federator().perform(:publish_one, params) do
|
|
{:ok, _} ->
|
|
:ok
|
|
|
|
{:error, _} = error ->
|
|
# Only mark as unreachable on final failure
|
|
if job.attempt == job.max_attempts do
|
|
Instances.set_unreachable(params.inbox)
|
|
end
|
|
|
|
error
|
|
|
|
error ->
|
|
# Unexpected error, may have been client side
|
|
error
|
|
end
|
|
end
|
|
end
|
|
|
|
@impl true
|
|
def timeout(_job), do: :timer.seconds(10)
|
|
|
|
defp federator, do: Config.get([:pipeline, :federator], Federator)
|
|
|
|
@base_backoff 15
|
|
@pow 5
|
|
@impl true
|
|
def backoff(%Job{attempt: attempt}) when is_integer(attempt) do
|
|
backoff =
|
|
:math.pow(attempt, @pow) +
|
|
@base_backoff +
|
|
:rand.uniform(2 * @base_backoff) * attempt
|
|
|
|
trunc(backoff)
|
|
end
|
|
end
|