Move caching to MobilizonWeb
This commit is contained in:
parent
8f580ce10c
commit
48dbec51f5
|
@ -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
|
||||||
%{
|
%{
|
||||||
|
|
|
@ -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.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -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.
|
||||||
"""
|
"""
|
||||||
|
|
24
lib/mobilizon_web/cache.ex
Normal file
24
lib/mobilizon_web/cache.ex
Normal 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
70
lib/mobilizon_web/cache/activity_pub.ex
vendored
Normal 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
|
|
@ -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}))
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
1
mix.exs
1
mix.exs
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue