From 2aead9edafb1645420a1bb899ee85fd556922d78 Mon Sep 17 00:00:00 2001 From: Cristen Jones Date: Tue, 17 Oct 2023 14:18:16 -0400 Subject: [PATCH] feat(Algolia.Api): cache requests --- apps/algolia/lib/algolia/api.ex | 18 +++++++++++++++--- apps/algolia/lib/algolia/application.ex | 3 +-- apps/algolia/mix.exs | 3 ++- apps/algolia/test/api_test.exs | 6 ++++-- 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/apps/algolia/lib/algolia/api.ex b/apps/algolia/lib/algolia/api.ex index fbb548d87a..c9a3b41d0e 100644 --- a/apps/algolia/lib/algolia/api.ex +++ b/apps/algolia/lib/algolia/api.ex @@ -4,6 +4,7 @@ defmodule Algolia.Api do """ alias Algolia.Config require Logger + use RepoCache, ttl: :timer.hours(12) defstruct [:host, :index, :action, :body] @@ -39,9 +40,20 @@ defmodule Algolia.Api do |> hackney_opts() |> Keyword.put(:pool, @http_pool) - opts - |> generate_url(config) - |> HTTPoison.post(body, headers(config), hackney: hackney) + send_post_request = fn {body, config} -> + opts + |> generate_url(config) + |> HTTPoison.post(body, headers(config), hackney: hackney) + end + + # If we're making a query for results using the same request body AND same + # %Algolia.Config{}, cache the response instead of making extra calls to the + # Algolia REST API + if action == "queries" do + cache({body, config}, send_post_request) + else + send_post_request.({body, config}) + end end @spec generate_url(t, Config.t()) :: String.t() diff --git a/apps/algolia/lib/algolia/application.ex b/apps/algolia/lib/algolia/application.ex index 81e3d094d4..9f23886108 100644 --- a/apps/algolia/lib/algolia/application.ex +++ b/apps/algolia/lib/algolia/application.ex @@ -8,8 +8,7 @@ defmodule Algolia.Application do def start(_type, _args) do # List all child processes to be supervised children = [ - # Starts a worker by calling: Algolia.Worker.start_link(arg) - # {Algolia.Worker, arg}, + Algolia.Api ] # See https://hexdocs.pm/elixir/Supervisor.html diff --git a/apps/algolia/mix.exs b/apps/algolia/mix.exs index 5feb42c9fc..abb5a2bd89 100644 --- a/apps/algolia/mix.exs +++ b/apps/algolia/mix.exs @@ -35,7 +35,8 @@ defmodule Algolia.Mixfile do {:util, in_umbrella: true}, {:httpoison, "~> 1.5"}, {:plug, "~> 1.14.2"}, - {:bypass, "~> 1.0", only: :test} + {:bypass, "~> 1.0", only: :test}, + {:repo_cache, in_umbrella: true} ] end end diff --git a/apps/algolia/test/api_test.exs b/apps/algolia/test/api_test.exs index 5249d1dbdb..4075c9e4c1 100644 --- a/apps/algolia/test/api_test.exs +++ b/apps/algolia/test/api_test.exs @@ -5,10 +5,10 @@ defmodule Algolia.ApiTest do @success_response ~s({"message" : "success"}) describe "post" do - test "sends a post request to /1/indexes/$INDEX/$ACTION" do + test "sends a post request once to /1/indexes/$INDEX/$ACTION" do bypass = Bypass.open() - Bypass.expect(bypass, "POST", "/1/indexes/*/queries", fn conn -> + Bypass.expect_once(bypass, "POST", "/1/indexes/*/queries", fn conn -> {:ok, body, conn} = Plug.Conn.read_body(conn) case Poison.decode(body) do @@ -29,6 +29,8 @@ defmodule Algolia.ApiTest do assert {:ok, %HTTPoison.Response{status_code: 200, body: body}} = Algolia.Api.post(opts) assert body == @success_response + # Can be called again with result from cache instead of hitting the API endpoint + assert {:ok, %HTTPoison.Response{status_code: 200, body: ^body}} = Algolia.Api.post(opts) end test "logs a warning if config keys are missing" do