diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index 63d70342a9..9548f31a03 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -158,7 +158,6 @@ defmodule Pleroma.Application do [ build_cachex("used_captcha", ttl_interval: seconds_valid_interval()), build_cachex("user", default_ttl: 25_000, ttl_interval: 1000, limit: 2500), - build_cachex("object", default_ttl: 25_000, ttl_interval: 1000, limit: 2500), build_cachex("scrubber", limit: 2500), build_cachex("scrubber_management", limit: 2500), build_cachex("idempotency", expiration: idempotency_expiration(), limit: 2500), diff --git a/lib/pleroma/caching_nebulex.ex b/lib/pleroma/caching_nebulex.ex new file mode 100644 index 0000000000..e2cd2d43c5 --- /dev/null +++ b/lib/pleroma/caching_nebulex.ex @@ -0,0 +1,12 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.CachingNebulex do + @callback put(key :: any(), value :: any(), opts :: Keyword.t()) :: :ok + @callback put(key :: any(), value :: any()) :: :ok + @callback get(key :: any(), opts :: Keyword.t()) :: any() + @callback get(key :: any()) :: any() + @callback delete(key :: any(), opts :: Keyword.t()) :: :ok + @callback delete(key :: any()) :: :ok +end diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex index 75f4ba5033..ff2b2a188e 100644 --- a/lib/pleroma/notification.ex +++ b/lib/pleroma/notification.ex @@ -540,7 +540,7 @@ defmodule Pleroma.Notification do # For some activities, only notify the author of the object def get_potential_receiver_ap_ids(%{data: %{"type" => type, "object" => object_id}}) when type in ~w{Like Announce EmojiReact} do - case Object.get_cached_by_ap_id(object_id) do + case Object.get_by_ap_id(object_id) do %Object{data: %{"actor" => actor}} -> [actor] diff --git a/lib/pleroma/object.ex b/lib/pleroma/object.ex index 77dfda8510..07657933df 100644 --- a/lib/pleroma/object.ex +++ b/lib/pleroma/object.ex @@ -4,11 +4,13 @@ defmodule Pleroma.Object do use Ecto.Schema + use Nebulex.Caching import Ecto.Query import Ecto.Changeset alias Pleroma.Activity + alias Pleroma.Cache alias Pleroma.Config alias Pleroma.Hashtag alias Pleroma.Object @@ -25,6 +27,7 @@ defmodule Pleroma.Object do @derive {Jason.Encoder, only: [:data]} @cachex Pleroma.Config.get([:cachex, :provider], Cachex) + @nebulex Pleroma.Config.get([:nebulex, :provider], Cache) schema "objects" do field(:data, :map) @@ -97,11 +100,16 @@ defmodule Pleroma.Object do defp hashtags_changed?(_, _), do: false def get_by_id(nil), do: nil - def get_by_id(id), do: Repo.get(Object, id) + def get_by_id(id), do: do_get_by_id(id) + + @decorate cacheable(cache: @nebulex, key: {Object, id}, opts: [ttl: 25_000]) + defp do_get_by_id(id), do: Repo.get(Object, id) def get_by_ap_id(nil), do: nil + def get_by_ap_id(ap_id), do: do_get_by_ap_id(ap_id) - def get_by_ap_id(ap_id) do + @decorate cacheable(cache: @nebulex, key: {Object, ap_id}, opts: [ttl: 25_000]) + defp do_get_by_ap_id(ap_id) do Repo.one(from(object in Object, where: fragment("(?)->>'id' = ?", object.data, ^ap_id))) end @@ -165,7 +173,7 @@ defmodule Pleroma.Object do end true -> - get_cached_by_ap_id(ap_id) + get_by_ap_id(ap_id) end end @@ -183,20 +191,6 @@ defmodule Pleroma.Object do # Legacy objects can be accessed by anybody def authorize_access(%Object{}, %User{}), do: :ok - @spec get_cached_by_ap_id(String.t()) :: Object.t() | nil - def get_cached_by_ap_id(ap_id) do - key = "object:#{ap_id}" - - with {:ok, nil} <- @cachex.get(:object_cache, key), - object when not is_nil(object) <- get_by_ap_id(ap_id), - {:ok, true} <- @cachex.put(:object_cache, key, object) do - object - else - {:ok, object} -> object - nil -> nil - end - end - def make_tombstone(%Object{data: %{"id" => id, "type" => type}}, deleted \\ DateTime.utc_now()) do %ObjectTombstone{ id: id, @@ -221,7 +215,7 @@ defmodule Pleroma.Object do def delete(%Object{data: %{"id" => id}} = object) do with {:ok, _obj} = swap_object_with_tombstone(object), deleted_activity = Activity.delete_all_by_object_ap_id(id), - {:ok, _} <- invalid_object_cache(object) do + {:ok, _} <- evict_cache(object) do cleanup_attachments( Config.get([:instance, :cleanup_attachments]), object @@ -242,25 +236,20 @@ defmodule Pleroma.Object do def prune(%Object{data: %{"id" => _id}} = object) do with {:ok, object} <- Repo.delete(object), - {:ok, _} <- invalid_object_cache(object) do + {:ok, _} <- evict_cache(object) do {:ok, object} end end - def invalid_object_cache(%Object{data: %{"id" => id}}) do - with {:ok, true} <- @cachex.del(:object_cache, "object:#{id}") do - @cachex.del(:web_resp_cache, URI.parse(id).path) - end - end - - def set_cache(%Object{data: %{"id" => ap_id}} = object) do - @cachex.put(:object_cache, "object:#{ap_id}", object) + def evict_cache(%Object{data: %{"id" => id}} = object) do + @cachex.del(:web_resp_cache, URI.parse(id).path) + @nebulex.delete({Object, id}) {:ok, object} end - def update_and_set_cache(changeset) do + def update_and_evict_cache(changeset) do with {:ok, object} <- Repo.update(changeset) do - set_cache(object) + evict_cache(object) end end @@ -282,7 +271,7 @@ defmodule Pleroma.Object do ) |> Repo.update_all([]) |> case do - {1, [object]} -> set_cache(object) + {1, [object]} -> evict_cache(object) _ -> {:error, "Not found"} end end @@ -309,7 +298,7 @@ defmodule Pleroma.Object do ) |> Repo.update_all([]) |> case do - {1, [object]} -> set_cache(object) + {1, [object]} -> evict_cache(object) _ -> {:error, "Not found"} end end @@ -332,7 +321,7 @@ defmodule Pleroma.Object do ) |> Repo.update_all([]) |> case do - {1, [object]} -> set_cache(object) + {1, [object]} -> evict_cache(object) _ -> {:error, "Not found"} end end @@ -355,7 +344,7 @@ defmodule Pleroma.Object do ) |> Repo.update_all([]) |> case do - {1, [object]} -> set_cache(object) + {1, [object]} -> evict_cache(object) _ -> {:error, "Not found"} end end @@ -384,7 +373,7 @@ defmodule Pleroma.Object do object |> Object.change(%{data: data}) - |> update_and_set_cache() + |> update_and_evict_cache() else _ -> :noop end diff --git a/lib/pleroma/object/fetcher.ex b/lib/pleroma/object/fetcher.ex index b54ef9ce56..65bdb18398 100644 --- a/lib/pleroma/object/fetcher.ex +++ b/lib/pleroma/object/fetcher.ex @@ -28,7 +28,7 @@ defmodule Pleroma.Object.Fetcher do with {:ok, new_data, _} <- ObjectValidator.validate(new_data, %{}), {:ok, new_data} <- MRF.filter(new_data), {:ok, new_object, _} <- - Object.Updater.do_update_and_invalidate_cache( + Object.Updater.do_update( object, new_data, _touch_changeset? = true @@ -67,7 +67,7 @@ defmodule Pleroma.Object.Fetcher do @spec fetch_object_from_id(String.t(), list()) :: {:ok, Object.t()} | {fetcher_errors(), any()} | Pipeline.errors() def fetch_object_from_id(id, options \\ []) do - with {_, nil} <- {:fetch_object, Object.get_cached_by_ap_id(id)}, + with {_, nil} <- {:fetch_object, Object.get_by_ap_id(id)}, {_, true} <- {:allowed_depth, Federator.allowed_thread_distance?(options[:depth])}, {_, {:ok, data}} <- {:fetch, fetch_and_contain_remote_object_from_id(id)}, {_, nil} <- {:normalize, Object.normalize(data, fetch: false)}, diff --git a/lib/pleroma/object/updater.ex b/lib/pleroma/object/updater.ex index b80bc7faf0..50ec0f782d 100644 --- a/lib/pleroma/object/updater.ex +++ b/lib/pleroma/object/updater.ex @@ -256,7 +256,7 @@ defmodule Pleroma.Object.Updater do defp maybe_touch_changeset(changeset, _), do: changeset - def do_update_and_invalidate_cache(orig_object, updated_object, touch_changeset? \\ false) do + def do_update(orig_object, updated_object, touch_changeset? \\ false) do orig_object_ap_id = updated_object["id"] orig_object_data = orig_object.data @@ -272,9 +272,7 @@ defmodule Pleroma.Object.Updater do |> Object.change(%{data: updated_object_data}) |> maybe_touch_changeset(touch_changeset?) - with {:ok, new_object} <- Repo.update(changeset), - {:ok, _} <- Object.invalid_object_cache(new_object), - {:ok, _} <- Object.set_cache(new_object), + with {:ok, new_object} <- Object.update_and_evict_cache(changeset), # The metadata/utils.ex uses the object id for the cache. {:ok, _} <- Pleroma.Activity.HTML.invalidate_cache_for(new_object.id) do if used_history_in_new_object? do diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 62c7a7b315..0cf871eb7d 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -1832,7 +1832,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do def enqueue_pin_fetches(%{pinned_objects: pins}) do # enqueue a task to fetch all pinned objects Enum.each(pins, fn {ap_id, _} -> - if is_nil(Object.get_cached_by_ap_id(ap_id)) do + if is_nil(Object.get_by_ap_id(ap_id)) do Pleroma.Workers.RemoteFetcherWorker.new(%{ "op" => "fetch_remote", "id" => ap_id, diff --git a/lib/pleroma/web/activity_pub/activity_pub_controller.ex b/lib/pleroma/web/activity_pub/activity_pub_controller.ex index 7ac0bbab4d..f4f209ee2c 100644 --- a/lib/pleroma/web/activity_pub/activity_pub_controller.ex +++ b/lib/pleroma/web/activity_pub/activity_pub_controller.ex @@ -80,7 +80,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do def object(%{assigns: assigns} = conn, _) do with ap_id <- Endpoint.url() <> conn.request_path, - %Object{} = object <- Object.get_cached_by_ap_id(ap_id), + %Object{} = object <- Object.get_by_ap_id(ap_id), user <- Map.get(assigns, :user, nil), {_, true} <- {:visible?, Visibility.visible_for_user?(object, user)} do conn diff --git a/lib/pleroma/web/activity_pub/object_validators/announce_validator.ex b/lib/pleroma/web/activity_pub/object_validators/announce_validator.ex index d0218583ea..937743539e 100644 --- a/lib/pleroma/web/activity_pub/object_validators/announce_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/announce_validator.ex @@ -81,7 +81,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AnnounceValidator do with actor when is_binary(actor) <- get_field(cng, :actor), object when is_binary(object) <- get_field(cng, :object), %User{} = actor <- User.get_cached_by_ap_id(actor), - %Object{} = object <- Object.get_cached_by_ap_id(object), + %Object{} = object <- Object.get_by_ap_id(object), false <- Visibility.public?(object) do same_actor = object.data["actor"] == actor.ap_id recipients = get_field(cng, :to) ++ get_field(cng, :cc) diff --git a/lib/pleroma/web/activity_pub/object_validators/common_validations.ex b/lib/pleroma/web/activity_pub/object_validators/common_validations.ex index 1c5b1a059a..cdb81b0a31 100644 --- a/lib/pleroma/web/activity_pub/object_validators/common_validations.ex +++ b/lib/pleroma/web/activity_pub/object_validators/common_validations.ex @@ -57,7 +57,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations do cng |> validate_change(field_name, fn field_name, object_id -> - object = Object.get_cached_by_ap_id(object_id) || Activity.get_by_ap_id(object_id) + object = Object.get_by_ap_id(object_id) || Activity.get_by_ap_id(object_id) cond do !object -> diff --git a/lib/pleroma/web/activity_pub/object_validators/create_chat_message_validator.ex b/lib/pleroma/web/activity_pub/object_validators/create_chat_message_validator.ex index b299647a14..7fda242878 100644 --- a/lib/pleroma/web/activity_pub/object_validators/create_chat_message_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/create_chat_message_validator.ex @@ -57,7 +57,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CreateChatMessageValidator do def validate_object_nonexistence(cng) do cng |> validate_change(:object, fn :object, object_id -> - if Object.get_cached_by_ap_id(object_id) do + if Object.get_by_ap_id(object_id) do [{:object, "The object to create already exists"}] else [] diff --git a/lib/pleroma/web/activity_pub/object_validators/create_generic_validator.ex b/lib/pleroma/web/activity_pub/object_validators/create_generic_validator.ex index 2395abfd4a..824c2fefee 100644 --- a/lib/pleroma/web/activity_pub/object_validators/create_generic_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/create_generic_validator.ex @@ -112,7 +112,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CreateGenericValidator do def validate_object_nonexistence(cng) do cng |> validate_change(:object, fn :object, object_id -> - if Object.get_cached_by_ap_id(object_id) do + if Object.get_by_ap_id(object_id) do [{:object, "The object to create already exists"}] else [] diff --git a/lib/pleroma/web/activity_pub/side_effects.ex b/lib/pleroma/web/activity_pub/side_effects.ex index d6d4036719..2b65523ebc 100644 --- a/lib/pleroma/web/activity_pub/side_effects.ex +++ b/lib/pleroma/web/activity_pub/side_effects.ex @@ -470,7 +470,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do if orig_object_data["type"] in Pleroma.Constants.updatable_object_types() do {:ok, _, updated} = - Object.Updater.do_update_and_invalidate_cache(orig_object, updated_object) + Object.Updater.do_update(orig_object, updated_object) if updated do object diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 6517f5effa..2440330ba2 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -728,7 +728,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do replies_uris = with limit when limit > 0 <- Pleroma.Config.get([:activitypub, :note_replies_output_limit], 0), - %Object{} = object <- Object.get_cached_by_ap_id(obj_data["id"]) do + %Object{} = object <- Object.get_by_ap_id(obj_data["id"]) do object |> Object.self_replies() |> select([o], fragment("?->>'id'", o.data)) diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index f30c92abfd..fa241624dd 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -327,7 +327,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do object |> Changeset.change(data: data) - |> Object.update_and_set_cache() + |> Object.update_and_evict_cache() end @spec add_emoji_reaction_to_object(Activity.t(), Object.t()) :: @@ -889,7 +889,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do {:ok, object} = activity.object |> Object.change(%{data: object_data}) - |> Object.update_and_set_cache() + |> Object.update_and_evict_cache() activity_data = activity.data diff --git a/lib/pleroma/web/activity_pub/views/user_view.ex b/lib/pleroma/web/activity_pub/views/user_view.ex index 61975387b3..fe1f042fce 100644 --- a/lib/pleroma/web/activity_pub/views/user_view.ex +++ b/lib/pleroma/web/activity_pub/views/user_view.ex @@ -281,7 +281,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do pinned_objects |> Enum.sort_by(fn {_, pinned_at} -> pinned_at end, &>=/2) |> Enum.map(fn {id, _} -> - ObjectView.render("object.json", %{object: Object.get_cached_by_ap_id(id)}) + ObjectView.render("object.json", %{object: Object.get_by_ap_id(id)}) end) %{ diff --git a/lib/pleroma/web/common_api.ex b/lib/pleroma/web/common_api.ex index 412424dae8..a5ba0d8b1d 100644 --- a/lib/pleroma/web/common_api.ex +++ b/lib/pleroma/web/common_api.ex @@ -357,7 +357,7 @@ defmodule Pleroma.Web.CommonAPI do Activity.normalize(activity.data) end) - object = Object.get_cached_by_ap_id(object.data["id"]) + object = Object.get_by_ap_id(object.data["id"]) {:ok, answer_activities, object} end end @@ -679,7 +679,7 @@ defmodule Pleroma.Web.CommonAPI do {:ok, object} = object |> Object.change(%{data: new_data}) - |> Object.update_and_set_cache() + |> Object.update_and_evict_cache() {:ok, Map.put(activity, :object, object)} end diff --git a/lib/pleroma/web/feed/feed_view.ex b/lib/pleroma/web/feed/feed_view.ex index e1ee33d62e..d1c2d81456 100644 --- a/lib/pleroma/web/feed/feed_view.ex +++ b/lib/pleroma/web/feed/feed_view.ex @@ -119,7 +119,7 @@ defmodule Pleroma.Web.Feed.FeedView do end def get_href(id) do - with %Object{data: %{"external_url" => external_url}} <- Object.get_cached_by_ap_id(id) do + with %Object{data: %{"external_url" => external_url}} <- Object.get_by_ap_id(id) do external_url else _e -> id diff --git a/test/pleroma/object_test.exs b/test/pleroma/object_test.exs index ed5c2b6c80..c7a528783b 100644 --- a/test/pleroma/object_test.exs +++ b/test/pleroma/object_test.exs @@ -55,26 +55,6 @@ defmodule Pleroma.ObjectTest do assert found_object.data["type"] == "Tombstone" end - - test "ensures cache is cleared for the object" do - object = insert(:note) - cached_object = Object.get_cached_by_ap_id(object.data["id"]) - - assert object == cached_object - - Cachex.put(:web_resp_cache, URI.parse(object.data["id"]).path, "cofe") - - Object.delete(cached_object) - - {:ok, nil} = Cachex.get(:object_cache, "object:#{object.data["id"]}") - {:ok, nil} = Cachex.get(:web_resp_cache, URI.parse(object.data["id"]).path) - - cached_object = Object.get_cached_by_ap_id(object.data["id"]) - - refute object == cached_object - - assert cached_object.data["type"] == "Tombstone" - end end describe "delete attachments" do diff --git a/test/pleroma/web/activity_pub/object_validators/announce_validation_test.exs b/test/pleroma/web/activity_pub/object_validators/announce_validation_test.exs index 5b2fcb26d4..2974a595ca 100644 --- a/test/pleroma/web/activity_pub/object_validators/announce_validation_test.exs +++ b/test/pleroma/web/activity_pub/object_validators/announce_validation_test.exs @@ -35,7 +35,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AnnounceValidationTest do test "keeps announced object context", %{valid_announce: valid_announce} do assert %Object{data: %{"context" => object_context}} = - Object.get_cached_by_ap_id(valid_announce["object"]) + Object.get_by_ap_id(valid_announce["object"]) {:ok, %{"context" => context}, _} = valid_announce diff --git a/test/pleroma/web/activity_pub/object_validators/delete_validation_test.exs b/test/pleroma/web/activity_pub/object_validators/delete_validation_test.exs index bbb31516c5..79bc7badb0 100644 --- a/test/pleroma/web/activity_pub/object_validators/delete_validation_test.exs +++ b/test/pleroma/web/activity_pub/object_validators/delete_validation_test.exs @@ -41,7 +41,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.DeleteValidationTest do {:ok, _object} = object |> Ecto.Changeset.change(%{data: data}) - |> Object.update_and_set_cache() + |> Object.update_and_evict_cache() {:error, cng} = ObjectValidator.validate(valid_post_delete, []) assert {:object, {"object not in allowed types", []}} in cng.errors diff --git a/test/pleroma/web/activity_pub/transmogrifier/delete_handling_test.exs b/test/pleroma/web/activity_pub/transmogrifier/delete_handling_test.exs index 300151fb21..34b1c8cff2 100644 --- a/test/pleroma/web/activity_pub/transmogrifier/delete_handling_test.exs +++ b/test/pleroma/web/activity_pub/transmogrifier/delete_handling_test.exs @@ -47,13 +47,10 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.DeleteHandlingTest do test "it works for incoming when the object has been pruned" do activity = insert(:note_activity) - {:ok, object} = + {:ok, _object} = Object.normalize(activity.data["object"], fetch: false) |> Repo.delete() - # TODO: mock cachex - Cachex.del(:object_cache, "object:#{object.data["id"]}") - deleting_user = insert(:user) data = diff --git a/test/pleroma/web/mastodon_api/views/status_view_test.exs b/test/pleroma/web/mastodon_api/views/status_view_test.exs index e6a164d723..ed74594a24 100644 --- a/test/pleroma/web/mastodon_api/views/status_view_test.exs +++ b/test/pleroma/web/mastodon_api/views/status_view_test.exs @@ -258,7 +258,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do |> Map.put("content", nil) Object.change(note_object, %{data: data}) - |> Object.update_and_set_cache() + |> Object.update_and_evict_cache() User.get_cached_by_ap_id(note.data["actor"]) diff --git a/test/support/data_case.ex b/test/support/data_case.ex index 304bee5daa..6e2913358f 100644 --- a/test/support/data_case.ex +++ b/test/support/data_case.ex @@ -67,6 +67,8 @@ defmodule Pleroma.DataCase do def setup_multi_process_mode(tags) do :ok = Ecto.Adapters.SQL.Sandbox.checkout(Pleroma.Repo) + Mox.stub_with(Pleroma.NebulexMock, Pleroma.VoidCache) + if tags[:async] do Mox.stub_with(Pleroma.CachexMock, Pleroma.NullCache) Mox.set_mox_private() diff --git a/test/support/mocks.ex b/test/support/mocks.ex index b268348712..a59c5fa318 100644 --- a/test/support/mocks.ex +++ b/test/support/mocks.ex @@ -3,6 +3,7 @@ # SPDX-License-Identifier: AGPL-3.0-only Mox.defmock(Pleroma.CachexMock, for: Pleroma.Caching) +Mox.defmock(Pleroma.NebulexMock, for: Pleroma.CachingNebulex) Mox.defmock(Pleroma.Web.ActivityPub.ObjectValidatorMock, for: Pleroma.Web.ActivityPub.ObjectValidator.Validating diff --git a/test/support/void_cache.ex b/test/support/void_cache.ex new file mode 100644 index 0000000000..cdb84c9314 --- /dev/null +++ b/test/support/void_cache.ex @@ -0,0 +1,19 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.VoidCache do + @moduledoc """ + A module simulating a permanently empty cache. + """ + @behaviour Pleroma.CachingNebulex + + @impl true + def put(_, _, _ \\ []), do: :ok + + @impl true + def get(_, _ \\ []), do: nil + + @impl true + def delete(_, _ \\ []), do: :ok +end diff --git a/test/test_helper.exs b/test/test_helper.exs index cbcea19f59..94661353b3 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -18,7 +18,6 @@ Ecto.Adapters.SQL.Sandbox.mode(Pleroma.Repo, :manual) Mox.defmock(Pleroma.ReverseProxy.ClientMock, for: Pleroma.ReverseProxy.Client) Mox.defmock(Pleroma.GunMock, for: Pleroma.Gun) -Mox.defmock(Pleroma.NebulexMock, for: Nebulex.Cache) {:ok, _} = Application.ensure_all_started(:ex_machina)