Move caching to MobilizonWeb

This commit is contained in:
miffigriffi 2019-09-17 23:39:26 +02:00
parent 8f580ce10c
commit 48dbec51f5
9 changed files with 112 additions and 81 deletions

View file

@ -351,17 +351,6 @@ defmodule Mobilizon.Actors.Actor do
|> URI.decode() |> URI.decode()
end end
@doc """
Clear multiple caches for an actor
"""
# TODO: move to MobilizonWeb
@spec clear_cache(t) :: {:ok, true}
def clear_cache(%__MODULE__{preferred_username: preferred_username, domain: nil}) do
Cachex.del(:activity_pub, "actor_" <> preferred_username)
Cachex.del(:feed, "actor_" <> preferred_username)
Cachex.del(:ics, "actor_" <> preferred_username)
end
@spec build_relay_creation_attrs(map) :: map @spec build_relay_creation_attrs(map) :: map
defp build_relay_creation_attrs(%{url: url, preferred_username: preferred_username}) do defp build_relay_creation_attrs(%{url: url, preferred_username: preferred_username}) do
%{ %{

View file

@ -160,24 +160,6 @@ defmodule Mobilizon.Actors do
|> Repo.preload(:organized_events) |> Repo.preload(:organized_events)
end end
@doc """
Gets a cached local actor by username.
#TODO: move to MobilizonWeb layer
"""
@spec get_cached_local_actor_by_name(String.t()) ::
{:commit, Actor.t()} | {:ignore, any()}
def get_cached_local_actor_by_name(name) do
Cachex.fetch(:activity_pub, "actor_" <> name, fn "actor_" <> name ->
case get_local_actor_by_name(name) do
nil ->
{:ignore, nil}
%Actor{} = actor ->
{:commit, actor}
end
end)
end
@doc """ @doc """
Creates an actor. Creates an actor.
""" """

View file

@ -225,21 +225,6 @@ defmodule Mobilizon.Events do
|> Repo.one() |> Repo.one()
end end
# TODO: move to MobilizonWeb
@spec get_cached_public_event_by_uuid_with_preload(String.t()) ::
{:commit, Event.t()} | {:ignore, nil}
def get_cached_public_event_by_uuid_with_preload(uuid) do
Cachex.fetch(:activity_pub, "event_" <> uuid, fn "event_" <> uuid ->
case get_public_event_by_uuid_with_preload(uuid) do
%Event{} = event ->
{:commit, event}
nil ->
{:ignore, nil}
end
end)
end
@doc """ @doc """
Creates an event. Creates an event.
""" """
@ -837,21 +822,6 @@ defmodule Mobilizon.Events do
|> Repo.preload(@comment_preloads) |> Repo.preload(@comment_preloads)
end end
# TODO: move to MobilizonWeb
@spec get_cached_comment_by_uuid_with_preload(String.t()) ::
{:commit, Comment.t()} | {:ignore, nil}
def get_cached_comment_by_uuid_with_preload(uuid) do
Cachex.fetch(:activity_pub, "comment_" <> uuid, fn "comment_" <> uuid ->
case get_comment_from_uuid_with_preload(uuid) do
%Comment{} = comment ->
{:commit, comment}
nil ->
{:ignore, nil}
end
end)
end
@doc """ @doc """
Creates a comment. Creates a comment.
""" """

View file

@ -0,0 +1,24 @@
defmodule MobilizonWeb.Cache do
@moduledoc """
Facade module which provides access to all cached data.
"""
alias Mobilizon.Actors.Actor
alias MobilizonWeb.Cache.ActivityPub
@caches [:activity_pub, :feed, :ics]
@doc """
Clears all caches for an actor.
"""
@spec clear_cache(Actor.t()) :: {:ok, true}
def clear_cache(%Actor{preferred_username: preferred_username, domain: nil}) do
Enum.each(@caches, &Cachex.del(&1, "actor_" <> preferred_username))
end
defdelegate get_local_actor_by_name(name), to: ActivityPub
defdelegate get_public_event_by_uuid_with_preload(uuid), to: ActivityPub
defdelegate get_comment_by_uuid_with_preload(uuid), to: ActivityPub
defdelegate get_relay, to: ActivityPub
end

70
lib/mobilizon_web/cache/activity_pub.ex vendored Normal file
View file

@ -0,0 +1,70 @@
defmodule MobilizonWeb.Cache.ActivityPub do
@moduledoc """
The ActivityPub related functions.
"""
alias Mobilizon.{Actors, Events, Service}
alias Mobilizon.Actors.Actor
alias Mobilizon.Events.{Comment, Event}
@cache :activity_pub
@doc """
Gets a local actor by username.
"""
@spec get_local_actor_by_name(String.t()) ::
{:commit, Actor.t()} | {:ignore, nil}
def get_local_actor_by_name(name) do
Cachex.fetch(@cache, "actor_" <> name, fn "actor_" <> name ->
case Actors.get_local_actor_by_name(name) do
%Actor{} = actor ->
{:commit, actor}
nil ->
{:ignore, nil}
end
end)
end
@doc """
Gets a public event by its UUID, with all associations loaded.
"""
@spec get_public_event_by_uuid_with_preload(String.t()) ::
{:commit, Event.t()} | {:ignore, nil}
def get_public_event_by_uuid_with_preload(uuid) do
Cachex.fetch(@cache, "event_" <> uuid, fn "event_" <> uuid ->
case Events.get_public_event_by_uuid_with_preload(uuid) do
%Event{} = event ->
{:commit, event}
nil ->
{:ignore, nil}
end
end)
end
@doc """
Gets a comment by its UUID, with all associations loaded.
"""
@spec get_comment_by_uuid_with_preload(String.t()) ::
{:commit, Comment.t()} | {:ignore, nil}
def get_comment_by_uuid_with_preload(uuid) do
Cachex.fetch(@cache, "comment_" <> uuid, fn "comment_" <> uuid ->
case Events.get_comment_from_uuid_with_preload(uuid) do
%Comment{} = comment ->
{:commit, comment}
nil ->
{:ignore, nil}
end
end)
end
@doc """
Gets a relay.
"""
@spec get_relay :: {:commit, Actor.t()} | {:ignore, nil}
def get_relay do
Cachex.fetch(@cache, "relay_actor", &Service.ActivityPub.Relay.get_actor/0)
end
end

View file

@ -11,6 +11,7 @@ defmodule MobilizonWeb.ActivityPubController do
alias Mobilizon.Service.Federator alias Mobilizon.Service.Federator
alias MobilizonWeb.ActivityPub.ActorView alias MobilizonWeb.ActivityPub.ActorView
alias MobilizonWeb.Cache
require Logger require Logger
@ -113,13 +114,7 @@ defmodule MobilizonWeb.ActivityPubController do
end end
def relay(conn, _params) do def relay(conn, _params) do
with {status, actor} <- with {:commit, %Actor{} = actor} <- Cache.get_relay() do
Cachex.fetch(
:activity_pub,
"relay_actor",
&Mobilizon.Service.ActivityPub.Relay.get_actor/0
),
true <- status in [:ok, :commit] do
conn conn
|> put_resp_header("content-type", "application/activity+json") |> put_resp_header("content-type", "application/activity+json")
|> json(ActorView.render("actor.json", %{actor: actor})) |> json(ActorView.render("actor.json", %{actor: actor}))

View file

@ -8,60 +8,60 @@ defmodule MobilizonWeb.FeedController do
def actor(conn, %{"name" => name, "format" => "atom"}) do def actor(conn, %{"name" => name, "format" => "atom"}) do
case Cachex.fetch(:feed, "actor_" <> name) do case Cachex.fetch(:feed, "actor_" <> name) do
{status, data} when status in [:ok, :commit] -> {:commit, data} ->
conn conn
|> put_resp_content_type("application/atom+xml") |> put_resp_content_type("application/atom+xml")
|> send_resp(200, data) |> send_resp(200, data)
_err -> _ ->
{:error, :not_found} {:error, :not_found}
end end
end end
def actor(conn, %{"name" => name, "format" => "ics"}) do def actor(conn, %{"name" => name, "format" => "ics"}) do
case Cachex.fetch(:ics, "actor_" <> name) do case Cachex.fetch(:ics, "actor_" <> name) do
{status, data} when status in [:ok, :commit] -> {:commit, data} ->
conn conn
|> put_resp_content_type("text/calendar") |> put_resp_content_type("text/calendar")
|> send_resp(200, data) |> send_resp(200, data)
_err -> _ ->
{:error, :not_found} {:error, :not_found}
end end
end end
def event(conn, %{"uuid" => uuid, "format" => "ics"}) do def event(conn, %{"uuid" => uuid, "format" => "ics"}) do
case Cachex.fetch(:ics, "event_" <> uuid) do case Cachex.fetch(:ics, "event_" <> uuid) do
{status, data} when status in [:ok, :commit] -> {:commit, data} ->
conn conn
|> put_resp_content_type("text/calendar") |> put_resp_content_type("text/calendar")
|> send_resp(200, data) |> send_resp(200, data)
_err -> _ ->
{:error, :not_found} {:error, :not_found}
end end
end end
def going(conn, %{"token" => token, "format" => "ics"}) do def going(conn, %{"token" => token, "format" => "ics"}) do
case Cachex.fetch(:ics, "token_" <> token) do case Cachex.fetch(:ics, "token_" <> token) do
{status, data} when status in [:ok, :commit] -> {:commit, data} ->
conn conn
|> put_resp_content_type("text/calendar") |> put_resp_content_type("text/calendar")
|> send_resp(200, data) |> send_resp(200, data)
_err -> _ ->
{:error, :not_found} {:error, :not_found}
end end
end end
def going(conn, %{"token" => token, "format" => "atom"}) do def going(conn, %{"token" => token, "format" => "atom"}) do
case Cachex.fetch(:feed, "token_" <> token) do case Cachex.fetch(:feed, "token_" <> token) do
{status, data} when status in [:ok, :commit] -> {:commit, data} ->
conn conn
|> put_resp_content_type("application/atom+xml") |> put_resp_content_type("application/atom+xml")
|> send_resp(200, data) |> send_resp(200, data)
_err -> {:ignore, _} ->
{:error, :not_found} {:error, :not_found}
end end
end end

View file

@ -3,8 +3,8 @@ defmodule MobilizonWeb.PageController do
Controller to load our webapp Controller to load our webapp
""" """
use MobilizonWeb, :controller use MobilizonWeb, :controller
alias Mobilizon.Actors
alias Mobilizon.Events alias MobilizonWeb.Cache
plug(:put_layout, false) plug(:put_layout, false)
action_fallback(MobilizonWeb.FallbackController) action_fallback(MobilizonWeb.FallbackController)
@ -12,17 +12,17 @@ defmodule MobilizonWeb.PageController do
def index(conn, _params), do: render(conn, :index) def index(conn, _params), do: render(conn, :index)
def actor(conn, %{"name" => name}) do def actor(conn, %{"name" => name}) do
{status, actor} = Actors.get_cached_local_actor_by_name(name) {status, actor} = Cache.get_local_actor_by_name(name)
render_or_error(conn, &ok_status?/2, status, :actor, actor) render_or_error(conn, &ok_status?/2, status, :actor, actor)
end end
def event(conn, %{"uuid" => uuid}) do def event(conn, %{"uuid" => uuid}) do
{status, event} = Events.get_cached_public_event_by_uuid_with_preload(uuid) {status, event} = Cache.get_public_event_by_uuid_with_preload(uuid)
render_or_error(conn, &ok_status_and_is_visible?/2, status, :event, event) render_or_error(conn, &ok_status_and_is_visible?/2, status, :event, event)
end end
def comment(conn, %{"uuid" => uuid}) do def comment(conn, %{"uuid" => uuid}) do
{status, comment} = Events.get_cached_comment_by_uuid_with_preload(uuid) {status, comment} = Cache.get_comment_by_uuid_with_preload(uuid)
render_or_error(conn, &ok_status_and_is_visible?/2, status, :comment, comment) render_or_error(conn, &ok_status_and_is_visible?/2, status, :comment, comment)
end end

View file

@ -236,6 +236,7 @@ defmodule Mobilizon.Mixfile do
MobilizonWeb.Router.Helpers, MobilizonWeb.Router.Helpers,
MobilizonWeb.AuthErrorHandler, MobilizonWeb.AuthErrorHandler,
MobilizonWeb.AuthPipeline, MobilizonWeb.AuthPipeline,
MobilizonWeb.Cache,
MobilizonWeb.ChangesetView, MobilizonWeb.ChangesetView,
MobilizonWeb.Context, MobilizonWeb.Context,
MobilizonWeb.Endpoint, MobilizonWeb.Endpoint,