X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fweb%2Fstreamer.ex;h=d64e6c393b0ddb71428a5027541d6b5808e32227;hb=78516a8daa7094506e0247e8bdaddfde77a4ba67;hp=cc38058946980ac0aff19de8cabe5e6532e6ae45;hpb=bd5bdc4c247e2ebb239215540a51b69c356da65c;p=akkoma diff --git a/lib/pleroma/web/streamer.ex b/lib/pleroma/web/streamer.ex index cc3805894..d64e6c393 100644 --- a/lib/pleroma/web/streamer.ex +++ b/lib/pleroma/web/streamer.ex @@ -1,9 +1,13 @@ defmodule Pleroma.Web.Streamer do use GenServer require Logger - import Plug.Conn + alias Pleroma.{User, Notification} def start_link do + spawn(fn -> + Process.sleep(1000 * 30) # 30 seconds + GenServer.cast(__MODULE__, %{action: :ping}) + end) GenServer.start_link(__MODULE__, %{}, name: __MODULE__) end @@ -11,17 +15,34 @@ defmodule Pleroma.Web.Streamer do GenServer.cast(__MODULE__, %{action: :add, socket: socket, topic: topic}) end + def remove_socket(topic, socket) do + GenServer.cast(__MODULE__, %{action: :remove, socket: socket, topic: topic}) + end + def stream(topic, item) do GenServer.cast(__MODULE__, %{action: :stream, topic: topic, item: item}) end - def handle_cast(%{action: :stream, topic: topic, item: item}, topics) do - Logger.debug("Trying to push to #{topic}") - Logger.debug("Pushing item to #{topic}") + def handle_cast(%{action: :ping}, topics) do + Map.values(topics) + |> List.flatten + |> Enum.each(fn (socket) -> + Logger.debug("Sending keepalive ping") + send socket.transport_pid, {:text, ""} + end) + spawn(fn -> + Process.sleep(1000 * 30) # 30 seconds + GenServer.cast(__MODULE__, %{action: :ping}) + end) + {:noreply, topics} + end + + def handle_cast(%{action: :stream, topic: "user", item: %Notification{} = item}, topics) do + topic = "user:#{item.user_id}" Enum.each(topics[topic] || [], fn (socket) -> json = %{ - event: "update", - payload: Pleroma.Web.MastodonAPI.StatusView.render("status.json", activity: item) |> Poison.encode! + event: "notification", + payload: Pleroma.Web.MastodonAPI.MastodonAPIController.render_notification(socket.assigns["user"], item) |> Poison.encode! } |> Poison.encode! send socket.transport_pid, {:text, json} @@ -29,7 +50,26 @@ defmodule Pleroma.Web.Streamer do {:noreply, topics} end + def handle_cast(%{action: :stream, topic: "user", item: item}, topics) do + Logger.debug("Trying to push to users") + recipient_topics = User.get_recipients_from_activity(item) + |> Enum.map(fn (%{id: id}) -> "user:#{id}" end) + + Enum.each(recipient_topics, fn (topic) -> + push_to_socket(topics, topic, item) + end) + {:noreply, topics} + end + + def handle_cast(%{action: :stream, topic: topic, item: item}, topics) do + Logger.debug("Trying to push to #{topic}") + Logger.debug("Pushing item to #{topic}") + push_to_socket(topics, topic, item) + {:noreply, topics} + end + def handle_cast(%{action: :add, topic: topic, socket: socket}, sockets) do + topic = internal_topic(topic, socket) sockets_for_topic = sockets[topic] || [] sockets_for_topic = Enum.uniq([socket | sockets_for_topic]) sockets = Map.put(sockets, topic, sockets_for_topic) @@ -38,8 +78,35 @@ defmodule Pleroma.Web.Streamer do {:noreply, sockets} end + def handle_cast(%{action: :remove, topic: topic, socket: socket}, sockets) do + topic = internal_topic(topic, socket) + sockets_for_topic = sockets[topic] || [] + sockets_for_topic = List.delete(sockets_for_topic, socket) + sockets = Map.put(sockets, topic, sockets_for_topic) + Logger.debug("Removed conn for #{topic}") + IO.inspect(sockets) + {:noreply, sockets} + end + def handle_cast(m, state) do IO.inspect("Unknown: #{inspect(m)}, #{inspect(state)}") {:noreply, state} end + + def push_to_socket(topics, topic, item) do + Enum.each(topics[topic] || [], fn (socket) -> + json = %{ + event: "update", + payload: Pleroma.Web.MastodonAPI.StatusView.render("status.json", activity: item, for: socket.assigns[:user]) |> Poison.encode! + } |> Poison.encode! + + send socket.transport_pid, {:text, json} + end) + end + + defp internal_topic("user", socket) do + "user:#{socket.assigns[:user].id}" + end + + defp internal_topic(topic, _), do: topic end