Add basic user caching.
authorRoger Braun <roger@rogerbraun.net>
Fri, 14 Apr 2017 15:13:51 +0000 (17:13 +0200)
committerRoger Braun <roger@rogerbraun.net>
Fri, 14 Apr 2017 15:13:51 +0000 (17:13 +0200)
Expires after 5 seconds.

lib/pleroma/application.ex
lib/pleroma/user.ex
lib/pleroma/web/twitter_api/twitter_api.ex
mix.exs
mix.lock
test/web/twitter_api/twitter_api_controller_test.exs
test/web/twitter_api/twitter_api_test.exs

index e88a85196924e42b774f321a86740c4255fa69a4..e5bd17ced4c96a8f71f00981f1bb0ddb2b6c83bb 100644 (file)
@@ -14,6 +14,10 @@ defmodule Pleroma.Application do
       supervisor(Pleroma.Web.Endpoint, []),
       # Start your own worker by calling: Pleroma.Worker.start_link(arg1, arg2, arg3)
       # worker(Pleroma.Worker, [arg1, arg2, arg3]),
+      supervisor(ConCache, [[
+                             ttl_check: :timer.seconds(1),
+                             ttl: :timer.seconds(5)
+                           ], [name: :users]])
     ]
 
     # See http://elixir-lang.org/docs/stable/elixir/Supervisor.html
index c77704db0c9b0184f78d072548b719a079b58cb5..0a443d22ac4f08a825bff5611cb8e249e56a3188 100644 (file)
@@ -52,4 +52,17 @@ defmodule Pleroma.User do
   def following?(%User{} = follower, %User{} = followed) do
     Enum.member?(follower.following, User.ap_followers(followed))
   end
+
+  def get_cached_by_ap_id(ap_id) do
+    ConCache.get_or_store(:users, "ap_id:#{ap_id}", fn() ->
+      # Return false so the cache will store it.
+      Repo.get_by(User, ap_id: ap_id) || false
+    end)
+  end
+
+  def get_cached_by_nickname(nickname) do
+    ConCache.get_or_store(:users, "nickname:#{nickname}", fn() ->
+      Repo.get_by(User, nickname: nickname) || false
+    end)
+  end
 end
index 19f3c1c8c0f34873b24a918ed4ec86f00f4ad538..d6ef0f4ed1b5bdf7ae759cca073ca06eba352f26 100644 (file)
@@ -175,7 +175,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
     Regex.scan(regex, text)
     |> List.flatten
     |> Enum.uniq
-    |> Enum.map(fn ("@" <> match = full_match) -> {full_match, Repo.get_by(User, nickname: match)} end)
+    |> Enum.map(fn ("@" <> match = full_match) -> {full_match, User.get_cached_by_nickname(match)} end)
     |> Enum.filter(fn ({_match, user}) -> user end)
   end
 
@@ -205,7 +205,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
   # For likes, fetch the liked activity, too.
   defp activity_to_status(%Activity{data: %{"type" => "Like"}} = activity, opts) do
     actor = get_in(activity.data, ["actor"])
-    user = Repo.get_by!(User, ap_id: actor)
+    user = User.get_cached_by_ap_id(actor)
     [liked_activity] = Activity.all_by_object_ap_id(activity.data["object"])
 
     ActivityRepresenter.to_map(activity, Map.merge(opts, %{user: user, liked_activity: liked_activity}))
@@ -213,8 +213,13 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
 
   defp activity_to_status(activity, opts) do
     actor = get_in(activity.data, ["actor"])
-    user = Repo.get_by!(User, ap_id: actor)
-    mentioned_users = Repo.all(from user in User, where: user.ap_id in ^activity.data["to"])
+    user = User.get_cached_by_ap_id(actor)
+    # mentioned_users = Repo.all(from user in User, where: user.ap_id in ^activity.data["to"])
+    mentioned_users = Enum.map(activity.data["to"], fn (ap_id) ->
+      User.get_cached_by_ap_id(ap_id)
+    end)
+    |> Enum.filter(&(&1))
+
     ActivityRepresenter.to_map(activity, Map.merge(opts, %{user: user, mentioned: mentioned_users}))
   end
 
diff --git a/mix.exs b/mix.exs
index 590ecfb092f5ef72e420d5ae78ff9149f6cb4df2..09bc34f1a5e417a7c036224ca05448461132b7fc 100644 (file)
--- a/mix.exs
+++ b/mix.exs
@@ -38,6 +38,7 @@ defmodule Pleroma.Mixfile do
      {:trailing_format_plug, "~> 0.0.5" },
      {:html_sanitize_ex, "~> 1.0.0"},
      {:calendar, "~> 0.16.1"},
+     {:con_cache, "~> 0.12.0"},
      {:ex_machina, "~> 2.0", only: :test},
      {:mix_test_watch, "~> 0.2", only: :dev}]
   end
index 2cf62ddca8f87a642fae9fd99b25229aebed0fdc..6fb72ac8a24e40749024d75e6d751e4a41b76574 100644 (file)
--- a/mix.lock
+++ b/mix.lock
@@ -1,6 +1,7 @@
 %{"calendar": {:hex, :calendar, "0.16.1", "782327ad8bae7c797b887840dc4ddb933f05ce6e333e5b04964d7a5d5f79bde3", [:mix], [{:tzdata, "~> 0.5.8 or ~> 0.1.201603", [hex: :tzdata, optional: false]}]},
   "certifi": {:hex, :certifi, "1.0.0", "1c787a85b1855ba354f0b8920392c19aa1d06b0ee1362f9141279620a5be2039", [:rebar3], []},
   "comeonin": {:hex, :comeonin, "3.0.2", "8b213268a6634bd2e31a8035a963e974681d13ccc1f73f2ae664b6ac4e993c96", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, optional: false]}]},
+  "con_cache": {:hex, :con_cache, "0.12.0", "2d961aec219aa5a914473873f348f5a6088292dc69d5192a9d25f8a1e13e9905", [:mix], [{:exactor, "~> 2.2.0", [hex: :exactor, optional: false]}]},
   "connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], []},
   "cowboy": {:hex, :cowboy, "1.1.2", "61ac29ea970389a88eca5a65601460162d370a70018afe6f949a29dca91f3bb0", [:rebar3], [{:cowlib, "~> 1.0.2", [hex: :cowlib, optional: false]}, {:ranch, "~> 1.3.2", [hex: :ranch, optional: false]}]},
   "cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [:make], []},
@@ -9,6 +10,7 @@
   "ecto": {:hex, :ecto, "2.1.4", "d1ba932813ec0e0d9db481ef2c17777f1cefb11fc90fa7c142ff354972dfba7e", [:mix], [{:db_connection, "~> 1.1", [hex: :db_connection, optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, optional: true]}]},
   "elixir_make": {:hex, :elixir_make, "0.4.0", "992f38fabe705bb45821a728f20914c554b276838433349d4f2341f7a687cddf", [:mix], []},
   "ex_machina": {:hex, :ex_machina, "2.0.0", "ec284c6f57233729cea9319e083f66e613e82549f78eccdb2059aeba5d0df9f3", [:mix], [{:ecto, "~> 2.1", [hex: :ecto, optional: true]}]},
+  "exactor": {:hex, :exactor, "2.2.3", "a6972f43bb6160afeb73e1d8ab45ba604cd0ac8b5244c557093f6e92ce582786", [:mix], []},
   "fs": {:hex, :fs, "2.12.0", "ad631efacc9a5683c8eaa1b274e24fa64a1b8eb30747e9595b93bec7e492e25e", [:rebar3], []},
   "gettext": {:hex, :gettext, "0.13.1", "5e0daf4e7636d771c4c71ad5f3f53ba09a9ae5c250e1ab9c42ba9edccc476263", [:mix], []},
   "hackney": {:hex, :hackney, "1.7.1", "e238c52c5df3c3b16ce613d3a51c7220a784d734879b1e231c9babd433ac1cb4", [:rebar3], [{:certifi, "1.0.0", [hex: :certifi, optional: false]}, {:idna, "4.0.0", [hex: :idna, optional: false]}, {:metrics, "1.0.1", [hex: :metrics, optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, optional: false]}]},
index 728a1b6a81a0a6c2903ace01192fa4ddde2e69bb..a4128f4420ad4483af214126c71f7098f7dcdbe2 100644 (file)
@@ -184,4 +184,10 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
     header_content = "Basic " <> Base.encode64("#{username}:#{password}")
     put_req_header(conn, "authorization", header_content)
   end
+
+  setup do
+    Supervisor.terminate_child(Pleroma.Supervisor, ConCache)
+    Supervisor.restart_child(Pleroma.Supervisor, ConCache)
+    :ok
+  end
 end
index 341622758f53af3b046ec0015f8b9c6706cd1088..040a392e5ec30a35c84bd0a7d980403a5ba91cac 100644 (file)
@@ -190,4 +190,10 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
 
     assert status == ActivityRepresenter.to_map(updated_activity, %{user: activity_user, for: user})
   end
+
+  setup do
+    Supervisor.terminate_child(Pleroma.Supervisor, ConCache)
+    Supervisor.restart_child(Pleroma.Supervisor, ConCache)
+    :ok
+  end
 end