Pipeline: Add a side effects step after the transaction finishes
This is to run things like streaming notifications out, which will sometimes need data that is created by the transaction, but is streamed out asynchronously.
This commit is contained in:
parent
65689ba9bd
commit
115d08a754
6 changed files with 169 additions and 29 deletions
|
|
@ -334,30 +334,34 @@ defmodule Pleroma.Notification do
|
|||
end
|
||||
end
|
||||
|
||||
def create_notifications(%Activity{data: %{"to" => _, "type" => "Create"}} = activity) do
|
||||
def create_notifications(activity, options \\ [])
|
||||
|
||||
def create_notifications(%Activity{data: %{"to" => _, "type" => "Create"}} = activity, options) do
|
||||
object = Object.normalize(activity, false)
|
||||
|
||||
if object && object.data["type"] == "Answer" do
|
||||
{:ok, []}
|
||||
else
|
||||
do_create_notifications(activity)
|
||||
do_create_notifications(activity, options)
|
||||
end
|
||||
end
|
||||
|
||||
def create_notifications(%Activity{data: %{"type" => type}} = activity)
|
||||
def create_notifications(%Activity{data: %{"type" => type}} = activity, options)
|
||||
when type in ["Follow", "Like", "Announce", "Move", "EmojiReact"] do
|
||||
do_create_notifications(activity)
|
||||
do_create_notifications(activity, options)
|
||||
end
|
||||
|
||||
def create_notifications(_), do: {:ok, []}
|
||||
def create_notifications(_, _), do: {:ok, []}
|
||||
|
||||
defp do_create_notifications(%Activity{} = activity, options) do
|
||||
do_send = Keyword.get(options, :do_send, true)
|
||||
|
||||
defp do_create_notifications(%Activity{} = activity) do
|
||||
{enabled_receivers, disabled_receivers} = get_notified_from_activity(activity)
|
||||
potential_receivers = enabled_receivers ++ disabled_receivers
|
||||
|
||||
notifications =
|
||||
Enum.map(potential_receivers, fn user ->
|
||||
do_send = user in enabled_receivers
|
||||
do_send = do_send && user in enabled_receivers
|
||||
create_notification(activity, user, do_send)
|
||||
end)
|
||||
|
||||
|
|
@ -623,4 +627,12 @@ defmodule Pleroma.Notification do
|
|||
end
|
||||
|
||||
def skip?(_, _, _), do: false
|
||||
|
||||
def for_user_and_activity(user, activity) do
|
||||
from(n in __MODULE__,
|
||||
where: n.user_id == ^user.id,
|
||||
where: n.activity_id == ^activity.id
|
||||
)
|
||||
|> Repo.one()
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -17,6 +17,10 @@ defmodule Pleroma.Web.ActivityPub.Pipeline do
|
|||
{:ok, Activity.t() | Object.t(), keyword()} | {:error, any()}
|
||||
def common_pipeline(object, meta) do
|
||||
case Repo.transaction(fn -> do_common_pipeline(object, meta) end) do
|
||||
{:ok, {:ok, activity, meta}} ->
|
||||
SideEffects.handle_after_transaction(meta)
|
||||
{:ok, activity, meta}
|
||||
|
||||
{:ok, value} ->
|
||||
value
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
|
|||
alias Pleroma.Web.ActivityPub.Pipeline
|
||||
alias Pleroma.Web.ActivityPub.Utils
|
||||
alias Pleroma.Web.Streamer
|
||||
alias Pleroma.Web.Push
|
||||
|
||||
def handle(object, meta \\ [])
|
||||
|
||||
|
|
@ -37,7 +38,12 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
|
|||
# - Set up notifications
|
||||
def handle(%{data: %{"type" => "Create"}} = activity, meta) do
|
||||
with {:ok, _object, _meta} <- handle_object_creation(meta[:object_data], meta) do
|
||||
Notification.create_notifications(activity)
|
||||
{:ok, notifications} = Notification.create_notifications(activity, do_send: false)
|
||||
|
||||
meta =
|
||||
meta
|
||||
|> add_notifications(notifications)
|
||||
|
||||
{:ok, activity, meta}
|
||||
else
|
||||
e -> Repo.rollback(e)
|
||||
|
|
@ -200,4 +206,26 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
|
|||
end
|
||||
|
||||
def handle_undoing(object), do: {:error, ["don't know how to handle", object]}
|
||||
|
||||
defp send_notifications(meta) do
|
||||
Keyword.get(meta, :created_notifications, [])
|
||||
|> Enum.each(fn notification ->
|
||||
Streamer.stream(["user", "user:notification"], notification)
|
||||
Push.send(notification)
|
||||
end)
|
||||
|
||||
meta
|
||||
end
|
||||
|
||||
defp add_notifications(meta, notifications) do
|
||||
existing = Keyword.get(meta, :created_notifications, [])
|
||||
|
||||
meta
|
||||
|> Keyword.put(:created_notifications, notifications ++ existing)
|
||||
end
|
||||
|
||||
def handle_after_transaction(meta) do
|
||||
meta
|
||||
|> send_notifications()
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue