From 9e230f8f0f431f235b48f85a74a4fc192c791c19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rio=20Rodrigues?= Date: Wed, 22 Jan 2025 02:08:57 +0000 Subject: [PATCH 1/3] feat: add redis --- config/config.exs | 6 ++++++ lib/cesium_link/application.ex | 1 + lib/cesium_link/links.ex | 12 ++++++++++++ lib/cesium_link/redis_cache.ex | 5 +++++ .../live/link_live/archived_live/index.ex | 2 ++ lib/cesium_link_web/live/link_live/form_component.ex | 3 +++ lib/cesium_link_web/live/link_live/index.ex | 2 ++ mix.exs | 1 + mix.lock | 4 ++++ 9 files changed, 36 insertions(+) create mode 100644 lib/cesium_link/redis_cache.ex diff --git a/config/config.exs b/config/config.exs index e18ccff..9870e15 100644 --- a/config/config.exs +++ b/config/config.exs @@ -32,6 +32,12 @@ config :esbuild, env: %{"NODE_PATH" => Path.expand("../deps", __DIR__)} ] +config :cesium_link, CesiumLink.Standalone, + conn_opts: [ + host: "localhost", + port: 6379 + ] + # Configure tailwind (the version is required) config :tailwind, version: "3.4.0", diff --git a/lib/cesium_link/application.ex b/lib/cesium_link/application.ex index fe1ac5f..b482f47 100644 --- a/lib/cesium_link/application.ex +++ b/lib/cesium_link/application.ex @@ -10,6 +10,7 @@ defmodule CesiumLink.Application do children = [ CesiumLinkWeb.Telemetry, CesiumLink.Repo, + CesiumLink.Standalone, {DNSCluster, query: Application.get_env(:cesium_link, :dns_cluster_query) || :ignore}, {Phoenix.PubSub, name: CesiumLink.PubSub}, # Start a worker by calling: CesiumLink.Worker.start_link(arg) diff --git a/lib/cesium_link/links.ex b/lib/cesium_link/links.ex index 9d05aa4..d26dc35 100644 --- a/lib/cesium_link/links.ex +++ b/lib/cesium_link/links.ex @@ -64,6 +64,18 @@ defmodule CesiumLink.Links do """ def list_unarchived_links_by_index do + case CesiumLink.Standalone.get("links") do + nil -> + links = list_unarchived_links_by_index_from_db() + CesiumLink.Standalone.put("links", links) + links + + links -> + links + end + end + + def list_unarchived_links_by_index_from_db do Repo.all(from l in Link, where: l.archived == false, order_by: [asc: l.index]) end diff --git a/lib/cesium_link/redis_cache.ex b/lib/cesium_link/redis_cache.ex new file mode 100644 index 0000000..e71029d --- /dev/null +++ b/lib/cesium_link/redis_cache.ex @@ -0,0 +1,5 @@ +defmodule CesiumLink.Standalone do + use Nebulex.Cache, + otp_app: :safira, + adapter: NebulexRedisAdapter +end diff --git a/lib/cesium_link_web/live/link_live/archived_live/index.ex b/lib/cesium_link_web/live/link_live/archived_live/index.ex index 53283eb..8a5cb9d 100644 --- a/lib/cesium_link_web/live/link_live/archived_live/index.ex +++ b/lib/cesium_link_web/live/link_live/archived_live/index.ex @@ -2,6 +2,7 @@ defmodule CesiumLinkWeb.ArchivedLive.Index do use CesiumLinkWeb, :admin_live_view alias CesiumLink.Links + alias CesiumLink.Standalone @impl true def mount(_params, _session, socket) do @@ -57,6 +58,7 @@ defmodule CesiumLinkWeb.ArchivedLive.Index do def handle_event("unarchive", %{"id" => id}, socket) do link = Links.get_link!(id) {:ok, _} = Links.unarchive_link(link) + Standalone.put("links", Links.list_unarchived_links_by_index_from_db()) {:noreply, stream_delete(socket, :links, link) diff --git a/lib/cesium_link_web/live/link_live/form_component.ex b/lib/cesium_link_web/live/link_live/form_component.ex index dff7386..174b285 100644 --- a/lib/cesium_link_web/live/link_live/form_component.ex +++ b/lib/cesium_link_web/live/link_live/form_component.ex @@ -2,6 +2,7 @@ defmodule CesiumLinkWeb.LinkLive.FormComponent do use CesiumLinkWeb, :live_component alias CesiumLink.Links + alias CesiumLink.Standalone @impl true def render(assigns) do @@ -58,6 +59,7 @@ defmodule CesiumLinkWeb.LinkLive.FormComponent do ) do {:ok, link} -> notify_parent({:saved, link}) + Standalone.put("links", Links.list_unarchived_links_by_index_from_db()) {:noreply, socket @@ -77,6 +79,7 @@ defmodule CesiumLinkWeb.LinkLive.FormComponent do ) do {:ok, link} -> notify_parent({:saved, link}) + Standalone.put("links", Links.list_unarchived_links_by_index_from_db()) {:noreply, socket diff --git a/lib/cesium_link_web/live/link_live/index.ex b/lib/cesium_link_web/live/link_live/index.ex index a1fa7c3..67b24fd 100644 --- a/lib/cesium_link_web/live/link_live/index.ex +++ b/lib/cesium_link_web/live/link_live/index.ex @@ -3,6 +3,7 @@ defmodule CesiumLinkWeb.LinkLive.Index do alias CesiumLink.Links alias CesiumLink.Links.Link + alias CesiumLink.Standalone @impl true def mount(_params, _session, socket) do @@ -47,6 +48,7 @@ defmodule CesiumLinkWeb.LinkLive.Index do def handle_event("archive", %{"id" => id}, socket) do link = Links.get_link!(id) {:ok, _} = Links.archive_link(link) + Standalone.put("links", Links.list_unarchived_links_by_index_from_db()) {:noreply, stream_delete(socket, :links, link) diff --git a/mix.exs b/mix.exs index ddca022..8e5041e 100644 --- a/mix.exs +++ b/mix.exs @@ -41,6 +41,7 @@ defmodule CesiumLink.MixProject do {:ecto_sql, "~> 3.10"}, {:phoenix_ecto, "~> 4.4"}, {:postgrex, ">= 0.0.0"}, + {:nebulex_redis_adapter, "~> 2.4.2"}, # auth {:elixir_auth_google, "~> 1.6.9"}, diff --git a/mix.lock b/mix.lock index 98e8447..6e87144 100644 --- a/mix.lock +++ b/mix.lock @@ -26,6 +26,9 @@ "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, "mime": {:hex, :mime, "2.0.6", "8f18486773d9b15f95f4f4f1e39b710045fa1de891fada4516559967276e4dc2", [:mix], [], "hexpm", "c9945363a6b26d747389aac3643f8e0e09d30499a138ad64fe8fd1d13d9b153e"}, "mimerl": {:hex, :mimerl, "1.3.0", "d0cd9fc04b9061f82490f6581e0128379830e78535e017f7780f37fea7545726", [:rebar3], [], "hexpm", "a1e15a50d1887217de95f0b9b0793e32853f7c258a5cd227650889b38839fe9d"}, + "nebulex": {:hex, :nebulex, "2.6.4", "4b00706e0e676474783d988962abf74614480e13c0a32645acb89bb32b660e09", [:mix], [{:decorator, "~> 1.4", [hex: :decorator, repo: "hexpm", optional: true]}, {:shards, "~> 1.1", [hex: :shards, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "25bdabf3fb86035c8151bba60bda20f80f96ae0261db7bd4090878ff63b03581"}, + "nebulex_redis_adapter": {:hex, :nebulex_redis_adapter, "2.4.2", "19f987e52fa5b31bf0d254736276a867820d2115834b05ee2d3f41cd62caf3a0", [:mix], [{:crc, "~> 0.10", [hex: :crc, repo: "hexpm", optional: true]}, {:jchash, "~> 0.1", [hex: :jchash, repo: "hexpm", optional: true]}, {:nebulex, "~> 2.6", [hex: :nebulex, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.5 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:redix, "~> 1.5", [hex: :redix, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "b9d8e4cf9c03f019b077d7a42530f57bac6dda619ddf40820d5e276ec6c346dd"}, + "nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"}, "parse_trans": {:hex, :parse_trans, "3.4.1", "6e6aa8167cb44cc8f39441d05193be6e6f4e7c2946cb2759f015f8c56b76e5ff", [:rebar3], [], "hexpm", "620a406ce75dada827b82e453c19cf06776be266f5a67cff34e1ef2cbb60e49a"}, "phoenix": {:hex, :phoenix, "1.7.14", "a7d0b3f1bc95987044ddada111e77bd7f75646a08518942c72a8440278ae7825", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.7", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:websock_adapter, "~> 0.5.3", [hex: :websock_adapter, repo: "hexpm", optional: false]}], "hexpm", "c7859bc56cc5dfef19ecfc240775dae358cbaa530231118a9e014df392ace61a"}, "phoenix_ecto": {:hex, :phoenix_ecto, "4.6.2", "3b83b24ab5a2eb071a20372f740d7118767c272db386831b2e77638c4dcc606d", [:mix], [{:ecto, "~> 3.5", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.1", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.16 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "3f94d025f59de86be00f5f8c5dd7b5965a3298458d21ab1c328488be3b5fcd59"}, @@ -38,6 +41,7 @@ "plug": {:hex, :plug, "1.16.1", "40c74619c12f82736d2214557dedec2e9762029b2438d6d175c5074c933edc9d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a13ff6b9006b03d7e33874945b2755253841b238c34071ed85b0e86057f8cddc"}, "plug_crypto": {:hex, :plug_crypto, "2.1.0", "f44309c2b06d249c27c8d3f65cfe08158ade08418cf540fd4f72d4d6863abb7b", [:mix], [], "hexpm", "131216a4b030b8f8ce0f26038bc4421ae60e4bb95c5cf5395e1421437824c4fa"}, "postgrex": {:hex, :postgrex, "0.19.0", "f7d50e50cb42e0a185f5b9a6095125a9ab7e4abccfbe2ab820ab9aa92b71dbab", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "dba2d2a0a8637defbf2307e8629cb2526388ba7348f67d04ec77a5d6a72ecfae"}, + "redix": {:hex, :redix, "1.5.2", "ab854435a663f01ce7b7847f42f5da067eea7a3a10c0a9d560fa52038fd7ab48", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:nimble_options, "~> 0.5.0 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "78538d184231a5d6912f20567d76a49d1be7d3fca0e1aaaa20f4df8e1142dcb8"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"}, "tailwind": {:hex, :tailwind, "0.2.3", "277f08145d407de49650d0a4685dc062174bdd1ae7731c5f1da86163a24dfcdb", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "8e45e7a34a676a7747d04f7913a96c770c85e6be810a1d7f91e713d3a3655b5d"}, "tailwind_formatter": {:hex, :tailwind_formatter, "0.3.7", "2728d031e6803dfddf63f1dd7c64b5b9fd70ffdf635709c50f47589f4fb48861", [:mix], [{:phoenix_live_view, ">= 0.17.6", [hex: :phoenix_live_view, repo: "hexpm", optional: true]}], "hexpm", "3d91ac4d4622505b09c0f4678512281515b4fbe7644f012da1bd2722f5880185"}, From 3aa381399ce6f0c928d87f12507fa642da04f1cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rio=20Rodrigues?= Date: Wed, 22 Jan 2025 02:21:24 +0000 Subject: [PATCH 2/3] fix: CI --- lib/cesium_link/links.ex | 16 +++++++++++++--- lib/cesium_link/redis_cache.ex | 3 +++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/lib/cesium_link/links.ex b/lib/cesium_link/links.ex index d26dc35..2781586 100644 --- a/lib/cesium_link/links.ex +++ b/lib/cesium_link/links.ex @@ -64,17 +64,27 @@ defmodule CesiumLink.Links do """ def list_unarchived_links_by_index do - case CesiumLink.Standalone.get("links") do - nil -> + case safe_get_from_redis("links") do + {:ok, nil} -> links = list_unarchived_links_by_index_from_db() CesiumLink.Standalone.put("links", links) links - links -> + {:ok, links} -> links + + {:error, _reason} -> + list_unarchived_links_by_index_from_db() end end + defp safe_get_from_redis(key) do + {:ok, CesiumLink.Standalone.get(key)} + rescue + exception -> + {:error, exception} + end + def list_unarchived_links_by_index_from_db do Repo.all(from l in Link, where: l.archived == false, order_by: [asc: l.index]) end diff --git a/lib/cesium_link/redis_cache.ex b/lib/cesium_link/redis_cache.ex index e71029d..7f49a6b 100644 --- a/lib/cesium_link/redis_cache.ex +++ b/lib/cesium_link/redis_cache.ex @@ -1,4 +1,7 @@ defmodule CesiumLink.Standalone do + @moduledoc """ + Standalone redis cache. + """ use Nebulex.Cache, otp_app: :safira, adapter: NebulexRedisAdapter From 1b14308b55c220ae0a1dfafe3e114e588d14f20d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rio=20Rodrigues?= Date: Wed, 22 Jan 2025 02:47:03 +0000 Subject: [PATCH 3/3] chore: Standalone --- lib/cesium_link/links.ex | 45 ++++++++++++++++--- lib/cesium_link/redis_cache.ex | 2 +- .../live/link_live/archived_live/index.ex | 2 - .../live/link_live/form_component.ex | 3 -- lib/cesium_link_web/live/link_live/index.ex | 2 - 5 files changed, 39 insertions(+), 15 deletions(-) diff --git a/lib/cesium_link/links.ex b/lib/cesium_link/links.ex index 2781586..19812a7 100644 --- a/lib/cesium_link/links.ex +++ b/lib/cesium_link/links.ex @@ -78,13 +78,6 @@ defmodule CesiumLink.Links do end end - defp safe_get_from_redis(key) do - {:ok, CesiumLink.Standalone.get(key)} - rescue - exception -> - {:error, exception} - end - def list_unarchived_links_by_index_from_db do Repo.all(from l in Link, where: l.archived == false, order_by: [asc: l.index]) end @@ -121,6 +114,14 @@ defmodule CesiumLink.Links do %Link{} |> Link.changeset(attrs) |> Repo.insert() + |> case do + {:ok, link} -> + safe_put_to_redis("links", list_unarchived_links_by_index_from_db()) + {:ok, link} + + error -> + error + end end @doc """ @@ -139,6 +140,14 @@ defmodule CesiumLink.Links do link |> Link.changeset(attrs) |> Repo.update() + |> case do + {:ok, link} -> + safe_put_to_redis("links", list_unarchived_links_by_index_from_db()) + {:ok, link} + + error -> + error + end end @doc """ @@ -155,6 +164,14 @@ defmodule CesiumLink.Links do """ def delete_link(%Link{} = link) do Repo.delete(link) + |> case do + {:ok, link} -> + safe_put_to_redis("links", list_unarchived_links_by_index_from_db()) + {:ok, link} + + error -> + error + end end @doc """ @@ -223,4 +240,18 @@ defmodule CesiumLink.Links do link |> update_link(%{visits: link.visits + 1}) end + + defp safe_get_from_redis(key) do + {:ok, CesiumLink.Standalone.get(key)} + rescue + exception -> + {:error, exception} + end + + defp safe_put_to_redis(key, value) do + {:ok, CesiumLink.Standalone.put(key, value)} + rescue + exception -> + {:error, exception} + end end diff --git a/lib/cesium_link/redis_cache.ex b/lib/cesium_link/redis_cache.ex index 7f49a6b..14a14c5 100644 --- a/lib/cesium_link/redis_cache.ex +++ b/lib/cesium_link/redis_cache.ex @@ -3,6 +3,6 @@ defmodule CesiumLink.Standalone do Standalone redis cache. """ use Nebulex.Cache, - otp_app: :safira, + otp_app: :cesium_link, adapter: NebulexRedisAdapter end diff --git a/lib/cesium_link_web/live/link_live/archived_live/index.ex b/lib/cesium_link_web/live/link_live/archived_live/index.ex index 8a5cb9d..53283eb 100644 --- a/lib/cesium_link_web/live/link_live/archived_live/index.ex +++ b/lib/cesium_link_web/live/link_live/archived_live/index.ex @@ -2,7 +2,6 @@ defmodule CesiumLinkWeb.ArchivedLive.Index do use CesiumLinkWeb, :admin_live_view alias CesiumLink.Links - alias CesiumLink.Standalone @impl true def mount(_params, _session, socket) do @@ -58,7 +57,6 @@ defmodule CesiumLinkWeb.ArchivedLive.Index do def handle_event("unarchive", %{"id" => id}, socket) do link = Links.get_link!(id) {:ok, _} = Links.unarchive_link(link) - Standalone.put("links", Links.list_unarchived_links_by_index_from_db()) {:noreply, stream_delete(socket, :links, link) diff --git a/lib/cesium_link_web/live/link_live/form_component.ex b/lib/cesium_link_web/live/link_live/form_component.ex index 174b285..dff7386 100644 --- a/lib/cesium_link_web/live/link_live/form_component.ex +++ b/lib/cesium_link_web/live/link_live/form_component.ex @@ -2,7 +2,6 @@ defmodule CesiumLinkWeb.LinkLive.FormComponent do use CesiumLinkWeb, :live_component alias CesiumLink.Links - alias CesiumLink.Standalone @impl true def render(assigns) do @@ -59,7 +58,6 @@ defmodule CesiumLinkWeb.LinkLive.FormComponent do ) do {:ok, link} -> notify_parent({:saved, link}) - Standalone.put("links", Links.list_unarchived_links_by_index_from_db()) {:noreply, socket @@ -79,7 +77,6 @@ defmodule CesiumLinkWeb.LinkLive.FormComponent do ) do {:ok, link} -> notify_parent({:saved, link}) - Standalone.put("links", Links.list_unarchived_links_by_index_from_db()) {:noreply, socket diff --git a/lib/cesium_link_web/live/link_live/index.ex b/lib/cesium_link_web/live/link_live/index.ex index 67b24fd..a1fa7c3 100644 --- a/lib/cesium_link_web/live/link_live/index.ex +++ b/lib/cesium_link_web/live/link_live/index.ex @@ -3,7 +3,6 @@ defmodule CesiumLinkWeb.LinkLive.Index do alias CesiumLink.Links alias CesiumLink.Links.Link - alias CesiumLink.Standalone @impl true def mount(_params, _session, socket) do @@ -48,7 +47,6 @@ defmodule CesiumLinkWeb.LinkLive.Index do def handle_event("archive", %{"id" => id}, socket) do link = Links.get_link!(id) {:ok, _} = Links.archive_link(link) - Standalone.put("links", Links.list_unarchived_links_by_index_from_db()) {:noreply, stream_delete(socket, :links, link)