From ed3cd5858cd27a90d4724a95ee660bbc08e92e80 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Thu, 17 Aug 2023 13:16:58 +0200 Subject: [PATCH] fix(backend): fix config cache not being used everytime When loading a page, we inject various meta tags in the HTML. These made database calls everytime Signed-off-by: Thomas Citharel --- .sobelow-skips | 61 +++++++-------------- lib/graphql/resolvers/admin.ex | 1 - lib/mobilizon/admin/admin.ex | 5 ++ lib/mobilizon/config.ex | 97 +++++++++++++++++++++++++++------- 4 files changed, 100 insertions(+), 64 deletions(-) diff --git a/.sobelow-skips b/.sobelow-skips index c75fab5e2..60c0c7623 100644 --- a/.sobelow-skips +++ b/.sobelow-skips @@ -1,45 +1,20 @@ -02CE4963DFD1B0D6D5C567357CAFFE97 155A1FB53DE39EC8EFCFD7FB94EA823D -2262742E5C8944D5BF6698EC61F5DE50 -25BEE162A99754480967216281E9EF33 -2A6F71CD6F1246F0B152C2376E2E398A -30552A09D485A6AA73401C1D54F63C21 -52900CE4EE3598F6F178A651FB256770 -6151F44368FC19F2394274F513C29151 -765526195D4C6D770EAF4DC944A8CBF4 -B2FF1A12F13B873507C85091688C1D6D -B9AF8A342CD7FF39E10CC10A408C28E1 -C042E87389F7BDCFF4E076E95731AE69 -C42BFAEF7100F57BED75998B217C857A -D11958E86F1B6D37EF656B63405CA8A4 -F16F054F2628609A726B9FF2F089D484 -26E816A7B054CB0347A2C6451F03B92B -2B76BDDB2BB4D36D69FAE793EBD63894 -301A837DE24C6AEE1DA812DF9E5486C1 -395A2740CB468F93F6EBE6E90EE08291 -4013C9866943B9381D9F9F97027F88A9 -4C796DD588A4B1C98E86BBCD0349949A -51289D8D7BDB59CB6473E0DED0591ED7 -5A70DC86895DB3610C605EA9F31ED300 -705C17F9C852F546D886B20DB2C4D0D1 -75D2074B6F771BA8C032008EC18CABDF -7B1C6E35A374C38FF5F07DBF23B3EAE2 -955ACF52ADD8FCAA450FB8138CB1FD1A -A092A563729E1F2C1C8D5D809A31F754 -BFA12FDEDEAD7DEAB6D44DF6FDFBD5E1 -D9A08930F140F9BA494BB90B3F812C87 -FE1EEB91EA633570F703B251AE2D4D4E -02B15A0FE85181E2470E4E1E6740DFF6 -128653EA565172F81FD177D1D6491CF3 -2EB031217231C480C89EA0C1576EF3CA -39CFFBCF3FD4F6DB0E4DE4A9A78D3961 -40C6EAD7C05ABB6A85BB904589DEF72F -49DE9560D506F9E7EF3AFD8DA6E5564B -759F752FA0768CCC7871895DC2A5CD51 -7EEC79571F3F7CEEB04A8B86D908382A -E7967805C1EA5301F2722C7BDB2F25F3 -BDFB0FB1AAF69C18212CBCFD42F8B717 -40220A533CCACB3A1CE9DBF1A8A430A1 -EEB29D1DDA3A3015BC645A989B5BD38E -5AEE3C678C80E0389C3B0D9D11886EB6 \ No newline at end of file +1C29EE70E90ECED01AF28EC58D2575B5 +31CE26BC979C57B9E3CC97B40C290CE5 +3529E7A4CECC24D02678820E6F521162 +4A4B7002DEB734A943B467DF7D2BD1AA +4E7C044C59E0BCB76AA826789998F624 +53CBBEB6243FAF5C37249CBA17DE6F4C +5BCE3651A03711295046DE48BDFE007E +630C0972985257251EDF89A7117DE423 +8274AF29B81EC7CF7F585D5EED8A64E1 +94ACF7B17C3FF42F64E57DD1DA936BD8 +A32E125003F1EDFAD95C487C6A969725 +ACF6272A1DBB3A2ABD96C0C120B5CA69 +C46C4893B2F702ACADC4CAA5683FE370 +CDF2CCE0CF10F49CDFAE22FE26208155 +E720CB13C50FF3ADEE7C522531E11217 +E8FC5F2C5DEA6671BA596B022C4FE6F2 +F3D5851D3FB050939841ED2F14307A27 +FD1C9756370A195B74E95CE504C45E9E \ No newline at end of file diff --git a/lib/graphql/resolvers/admin.ex b/lib/graphql/resolvers/admin.ex index c1f664015..b5d6fa1ee 100644 --- a/lib/graphql/resolvers/admin.ex +++ b/lib/graphql/resolvers/admin.ex @@ -273,7 +273,6 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do |> Enum.into(%{}), :ok <- eventually_update_instance_actor(res) do Config.clear_config_cache() - Cachex.put(:config, :admin_config, res) {:ok, res} end diff --git a/lib/mobilizon/admin/admin.ex b/lib/mobilizon/admin/admin.ex index c184bcba4..9a93b02f1 100644 --- a/lib/mobilizon/admin/admin.ex +++ b/lib/mobilizon/admin/admin.ex @@ -78,6 +78,11 @@ defmodule Mobilizon.Admin do defp stringify_struct(struct), do: struct + @spec get_all_admin_settings :: list(Setting.t()) + def get_all_admin_settings do + Repo.all(Setting) + end + @spec get_admin_setting_value(String.t(), String.t(), String.t() | nil) :: String.t() | boolean() | nil | map() | list() def get_admin_setting_value(group, name, fallback \\ nil) diff --git a/lib/mobilizon/config.ex b/lib/mobilizon/config.ex index abafe9ece..e27d7c9a2 100644 --- a/lib/mobilizon/config.ex +++ b/lib/mobilizon/config.ex @@ -4,6 +4,7 @@ defmodule Mobilizon.Config do """ alias Mobilizon.Actors + alias Mobilizon.Admin.Setting alias Mobilizon.Service.GitStatus require Logger import Mobilizon.Service.Export.Participants.Common, only: [enabled_formats: 0] @@ -28,10 +29,67 @@ defmodule Mobilizon.Config do @spec instance_config :: mobilizon_config def instance_config, do: Application.get_env(:mobilizon, :instance) + @spec db_instance_config :: list(Setting.t()) + def db_instance_config, do: Mobilizon.Admin.get_all_admin_settings() + + @spec config_cache :: map() + def config_cache do + case Cachex.fetch(:config, :all_db_config, fn _key -> + value = + Enum.reduce( + Mobilizon.Admin.get_all_admin_settings(), + %{}, + &arrange_values/2 + ) + + {:commit, value} + end) do + {status, value} when status in [:ok, :commit] -> value + _err -> %{} + end + end + + @spec arrange_values(Setting.t(), map()) :: map() + defp arrange_values(setting, acc) do + {_, new_data} = + Map.get_and_update(acc, setting.group, fn current_value -> + new_value = current_value || %{} + + {current_value, Map.put(new_value, setting.name, process_value(setting.value))} + end) + + new_data + end + + @spec process_value(String.t() | nil) :: any() + defp process_value(nil), do: nil + defp process_value(""), do: nil + + defp process_value(value) do + case Jason.decode(value) do + {:ok, val} -> + val + + {:error, _} -> + case value do + "true" -> true + "false" -> false + value -> value + end + end + end + + @spec config_cached_value(String.t(), String.t(), String.t()) :: any() + def config_cached_value(group, name, fallback \\ nil) do + config_cache() + |> Map.get(group, %{}) + |> Map.get(name, fallback) + end + @spec instance_name :: String.t() def instance_name, do: - Mobilizon.Admin.get_admin_setting_value( + config_cached_value( "instance", "instance_name", instance_config()[:name] @@ -40,7 +98,7 @@ defmodule Mobilizon.Config do @spec instance_description :: String.t() def instance_description, do: - Mobilizon.Admin.get_admin_setting_value( + config_cached_value( "instance", "instance_description", instance_config()[:description] @@ -49,37 +107,37 @@ defmodule Mobilizon.Config do @spec instance_long_description :: String.t() def instance_long_description, do: - Mobilizon.Admin.get_admin_setting_value( + config_cached_value( "instance", "instance_long_description" ) @spec instance_slogan :: String.t() | nil - def instance_slogan, do: Mobilizon.Admin.get_admin_setting_value("instance", "instance_slogan") + def instance_slogan, do: config_cached_value("instance", "instance_slogan") @spec contact :: String.t() | nil def contact do - Mobilizon.Admin.get_admin_setting_value("instance", "contact") + config_cached_value("instance", "contact") end @spec instance_terms(String.t()) :: String.t() def instance_terms(locale \\ "en") do - Mobilizon.Admin.get_admin_setting_value("instance", "instance_terms", generate_terms(locale)) + config_cached_value("instance", "instance_terms", generate_terms(locale)) end @spec instance_terms_type :: String.t() def instance_terms_type do - Mobilizon.Admin.get_admin_setting_value("instance", "instance_terms_type", "DEFAULT") + config_cached_value("instance", "instance_terms_type", "DEFAULT") end @spec instance_terms_url :: String.t() | nil def instance_terms_url do - Mobilizon.Admin.get_admin_setting_value("instance", "instance_terms_url") + config_cached_value("instance", "instance_terms_url") end @spec instance_privacy(String.t()) :: String.t() def instance_privacy(locale \\ "en") do - Mobilizon.Admin.get_admin_setting_value( + config_cached_value( "instance", "instance_privacy_policy", generate_privacy(locale) @@ -88,17 +146,17 @@ defmodule Mobilizon.Config do @spec instance_privacy_type :: String.t() def instance_privacy_type do - Mobilizon.Admin.get_admin_setting_value("instance", "instance_privacy_policy_type", "DEFAULT") + config_cached_value("instance", "instance_privacy_policy_type", "DEFAULT") end @spec instance_privacy_url :: String.t() def instance_privacy_url do - Mobilizon.Admin.get_admin_setting_value("instance", "instance_privacy_policy_url") + config_cached_value("instance", "instance_privacy_policy_url") end @spec instance_rules :: String.t() def instance_rules do - Mobilizon.Admin.get_admin_setting_value("instance", "instance_rules") + config_cached_value("instance", "instance_rules") end @spec instance_version :: String.t() @@ -113,7 +171,7 @@ defmodule Mobilizon.Config do def instance_registrations_open?, do: to_boolean( - Mobilizon.Admin.get_admin_setting_value( + config_cached_value( "instance", "registrations_open", instance_config()[:registrations_open] @@ -123,7 +181,7 @@ defmodule Mobilizon.Config do @spec instance_languages :: list(String.t()) def instance_languages, do: - Mobilizon.Admin.get_admin_setting_value( + config_cached_value( "instance", "instance_languages", instance_config()[:languages] @@ -322,8 +380,6 @@ defmodule Mobilizon.Config do @spec anonymous_actor_id :: integer def anonymous_actor_id, do: get_cached_value(:anonymous_actor_id) - @spec admin_settings :: map - def admin_settings, do: get_cached_value(:admin_config) @spec get(keys :: module | atom | [module | atom]) :: any def get(key), do: get(key, nil) @@ -399,8 +455,11 @@ defmodule Mobilizon.Config do end end - defp create_cache(:admin_config) do - data = %{ + defp create_cache(_), do: {:error, :cache_key_not_handled} + + @spec admin_settings :: map() + def admin_settings do + %{ instance_description: instance_description(), instance_long_description: instance_long_description(), instance_name: instance_name(), @@ -416,8 +475,6 @@ defmodule Mobilizon.Config do instance_rules: instance_rules(), instance_languages: instance_languages() } - - {:ok, data} end @spec clear_config_cache :: {:ok | :error, integer}