[#3213] Misc. tweaks: proper upsert in Hashtag, better feature toggle management.
authorIvan Tashkinov <ivantashkinov@gmail.com>
Tue, 23 Feb 2021 10:52:28 +0000 (13:52 +0300)
committerIvan Tashkinov <ivantashkinov@gmail.com>
Tue, 23 Feb 2021 10:52:28 +0000 (13:52 +0300)
config/config.exs
config/description.exs
docs/configuration/cheatsheet.md
lib/pleroma/config.ex
lib/pleroma/hashtag.ex
lib/pleroma/migrators/hashtags_table_migrator.ex
lib/pleroma/web/activity_pub/activity_pub.ex
test/pleroma/web/activity_pub/activity_pub_test.exs

index c371c397ce966bf46f7f498f03a741d04996c82a..05acbf1696b47c68059fe21db487c45e58c831bc 100644 (file)
@@ -657,6 +657,8 @@ config :pleroma, :oauth2,
 
 config :pleroma, :database, rum_enabled: false
 
+config :pleroma, :features, improved_hashtag_timeline: :auto
+
 config :pleroma, :populate_hashtags_table, fault_rate_allowance: 0.01
 
 config :pleroma, :env, Mix.env()
index e280ed8cf57665e216731f3edc92c1ae6792f0be..41e5e4056e6b3e79e7dee9ce470f546239c5e209 100644 (file)
@@ -461,15 +461,16 @@ config :pleroma, :config_description, [
   },
   %{
     group: :pleroma,
-    key: :database,
+    key: :features,
     type: :group,
-    description: "Database-related settings",
+    description: "Customizable features",
     children: [
       %{
         key: :improved_hashtag_timeline,
-        type: :keyword,
+        type: {:dropdown, :atom},
         description:
-          "If `true`, hashtags will be fetched from `hashtags` table for hashtags timeline. When `false`, object-embedded hashtags will be used (slower). Is auto-set to `true` (unless overridden) when HashtagsTableMigrator completes."
+          "Setting to force toggle / force disable improved hashtags timeline. `:enabled` forces hashtags to be fetched from `hashtags` table for hashtags timeline. `:disabled` forces object-embedded hashtags to be used (slower). Keep it `:auto` for automatic behaviour (it is auto-set to `:enabled` [unless overridden] when HashtagsTableMigrator completes).",
+        suggestions: [:auto, :enabled, :disabled]
       }
     ]
   },
index 6a1031f15077869b78893c656d43f1f451c072c4..db1deb6653fc4b318e89771012b96618de330a30 100644 (file)
@@ -66,7 +66,7 @@ To add configuration to your config file, you can copy it from the base config.
 * `password_reset_token_validity`: The time after which reset tokens aren't accepted anymore, in seconds (default: one day).
 
 ## :database
-* `improved_hashtag_timeline`: If `true`, hashtags will be fetched from `hashtags` table for hashtags timeline. When `false`, object-embedded hashtags will be used (slower). Is auto-set to `true` (unless overridden) when `HashtagsTableMigrator` completes.
+* `improved_hashtag_timeline`: Setting to force toggle / force disable improved hashtags timeline. `:enabled` forces hashtags to be fetched from `hashtags` table for hashtags timeline. `:disabled` forces object-embedded hashtags to be used (slower). Keep it `:auto` for automatic behaviour (it is auto-set to `:enabled` [unless overridden] when HashtagsTableMigrator completes).
 
 ## Background migrations
 * `populate_hashtags_table/sleep_interval_ms`: Sleep interval between each chunk of processed records in order to decrease the load on the system (defaults to 0 and should be keep default on most instances).
index f17e141282883d7c29e876a253003556a66a7747..e057d8c020203b4d7db65515c162c4953ab62f5c 100644 (file)
@@ -111,4 +111,8 @@ defmodule Pleroma.Config do
       end
     )
   end
+
+  def feature_enabled?(feature_name) do
+    get([:features, feature_name]) not in [nil, false, :disabled, :auto]
+  end
 end
index e9d143fb18359b553cb4f6e8b959e5cd7de1653b..53e2e9c897d564dd788306a72fa640ff75cbdce8 100644 (file)
@@ -27,19 +27,15 @@ defmodule Pleroma.Hashtag do
     |> String.trim()
   end
 
-  def get_by_name(name) do
-    Repo.get_by(Hashtag, name: normalize_name(name))
-  end
-
-  def get_or_create_by_name(name) when is_bitstring(name) do
-    with %Hashtag{} = hashtag <- get_by_name(name) do
-      {:ok, hashtag}
-    else
-      _ ->
-        %Hashtag{}
-        |> changeset(%{name: name})
-        |> Repo.insert()
-    end
+  def get_or_create_by_name(name) do
+    changeset = changeset(%Hashtag{}, %{name: name})
+
+    Repo.insert(
+      changeset,
+      on_conflict: [set: [name: get_field(changeset, :name)]],
+      conflict_target: :name,
+      returning: true
+    )
   end
 
   def get_or_create_by_names(names) when is_list(names) do
index 07bb9aeb292f2f8de1e82d31dc50443d5912746b..6123c88e0831761f77582afa472d61c6e47b02c3 100644 (file)
@@ -24,7 +24,7 @@ defmodule Pleroma.Migrators.HashtagsTableMigrator do
   defdelegate put_stat(key, value), to: State, as: :put_data_key
   defdelegate increment_stat(key, increment), to: State, as: :increment_data_key
 
-  @feature_config_path [:database, :improved_hashtag_timeline]
+  @feature_config_path [:features, :improved_hashtag_timeline]
   @reg_name {:global, __MODULE__}
 
   def whereis, do: GenServer.whereis(@reg_name)
@@ -296,16 +296,12 @@ defmodule Pleroma.Migrators.HashtagsTableMigrator do
   end
 
   defp on_complete(data_migration) do
-    cond do
-      data_migration.feature_lock ->
-        :noop
-
-      not is_nil(feature_state()) ->
-        :noop
-
-      true ->
-        Config.put(@feature_config_path, true)
-        :ok
+    if data_migration.feature_lock || feature_state() == :disabled do
+      Logger.warn("#{__MODULE__}: migration complete but feature is locked; consider enabling.")
+      :noop
+    else
+      Config.put(@feature_config_path, :enabled)
+      :ok
     end
   end
 
index 8182bc20504d10faf2b58b6a48e3ea228aa31f4b..9d557c2cdf8781e50a1be5684bd9dcc85dd64824 100644 (file)
@@ -1273,7 +1273,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
       |> exclude_invisible_actors(opts)
       |> exclude_visibility(opts)
 
-    if Config.get([:database, :improved_hashtag_timeline]) do
+    if Config.feature_enabled?(:improved_hashtag_timeline) do
       query
       |> restrict_hashtag_any(opts)
       |> restrict_hashtag_all(opts)
index c41c8a5dd910c0799cd1bdf0cbe090e02742d89e..f92323abe916c7e65053b5a8a845f563aff13cbb 100644 (file)
@@ -220,8 +220,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
     {:ok, status_four} = CommonAPI.post(user, %{status: ". #Any1 #any2"})
     {:ok, status_five} = CommonAPI.post(user, %{status: ". #Any2 #any1"})
 
-    for hashtag_timeline_strategy <- [true, false] do
-      clear_config([:database, :improved_hashtag_timeline], hashtag_timeline_strategy)
+    for hashtag_timeline_strategy <- [:eanbled, :disabled] do
+      clear_config([:features, :improved_hashtag_timeline], hashtag_timeline_strategy)
 
       fetch_one = ActivityPub.fetch_activities([], %{type: "Create", tag: "test"})