This is an automated email from the ASF dual-hosted git repository.
vatamane pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/couchdb.git
The following commit(s) were added to refs/heads/main by this push:
new 6c3e889ad Allow infinity for auto purge ttl setting
6c3e889ad is described below
commit 6c3e889ad62fba446e7e3b89cf92e4a299ec0929
Author: Nick Vatamaniuc <[email protected]>
AuthorDate: Wed Feb 25 02:23:13 2026 -0500
Allow infinity for auto purge ttl setting
The explicit `infinity` value can work better with multiple config levels.
Also, users can now enable ttl for the whole cluster but disable it for
specific dbs by setting their ttl in {db}/_auto_purge to `infinity`.
While at it, update the etc default.ini config comment since we switched to
using the `{num}_{timeunit}` format.
---
rel/overlay/etc/default.ini | 8 +++--
src/chttpd/src/chttpd_db.erl | 4 +++
src/couch/src/couch_auto_purge_plugin.erl | 21 +++++++++---
.../test/eunit/couch_auto_purge_plugin_tests.erl | 38 ++++++++++++++++++++++
src/docs/src/config/scanner.rst | 9 +++--
5 files changed, 70 insertions(+), 10 deletions(-)
diff --git a/rel/overlay/etc/default.ini b/rel/overlay/etc/default.ini
index 6fbc99f58..462233d47 100644
--- a/rel/overlay/etc/default.ini
+++ b/rel/overlay/etc/default.ini
@@ -1224,9 +1224,11 @@ url = {{nouveau_url}}
; one request.
;max_batch_size = 500
-; The default time-to-live, measured in seconds, before a
-; deleted document is eligible to be purged by the plugin.
-; Defaults to undefined, which disables auto purging.
+; The default time-to-live before a deleted document is eligible to be purged
+; by the plugin. Possible formats are: {num}_{timeunit} (ex: 1000_sec, 30_min,
+; 8_hours, 24_hours, 2_days, 3_weeks, 1_month, 2_years). Defaults to undefined
+; (or "infinity") which disables auto purging. Individual database ttl settings
+; will override this value.
;deleted_document_ttl =
; Set the log level for starting, stopping and purge report summary log
entries.
diff --git a/src/chttpd/src/chttpd_db.erl b/src/chttpd/src/chttpd_db.erl
index 5ef69f33f..200e705d2 100644
--- a/src/chttpd/src/chttpd_db.erl
+++ b/src/chttpd/src/chttpd_db.erl
@@ -412,6 +412,10 @@ handle_auto_purge_req(#httpd{} = Req, _Db) ->
validate_auto_purge_props([]) ->
ok;
+validate_auto_purge_props([{<<"deleted_document_ttl">>, <<"infinity">>} |
Rest]) ->
+ % Setting the value to "infinity" is way to explicilty disable auto-purge
+ % individual databases while allowing cluster level auto-purge to happen
+ validate_auto_purge_props(Rest);
validate_auto_purge_props([{<<"deleted_document_ttl">>, Value} | Rest]) when
is_binary(Value) ->
case couch_scanner_util:parse_non_weekday_period(?b2l(Value)) of
undefined ->
diff --git a/src/couch/src/couch_auto_purge_plugin.erl
b/src/couch/src/couch_auto_purge_plugin.erl
index 4fd904fdd..5589be244 100644
--- a/src/couch/src/couch_auto_purge_plugin.erl
+++ b/src/couch/src/couch_auto_purge_plugin.erl
@@ -197,6 +197,8 @@ ttl(St, DbName) ->
case parse_deleted_document_ttl(AutoPurgeProps) of
TTL when is_integer(TTL) ->
TTL;
+ infinity ->
+ infinity;
undefined ->
undefined;
Else ->
@@ -215,22 +217,33 @@ ttl(St, DbName) ->
),
undefined
end,
- if
- DbTTL /= undefined -> DbTTL;
- DefaultTTL /= undefined -> parse_ttl(DefaultTTL);
- true -> undefined
+ case {DbTTL, DefaultTTL} of
+ {undefined, undefined} ->
+ undefined;
+ {undefined, infinity} ->
+ undefined;
+ {infinity, _} ->
+ undefined;
+ {undefined, Val} when is_list(Val) ->
+ parse_ttl(Val);
+ {Val, _} when is_integer(Val) ->
+ Val
end.
parse_deleted_document_ttl(AutoPurgeProps) ->
case couch_util:get_value(<<"deleted_document_ttl">>, AutoPurgeProps) of
undefined ->
undefined;
+ <<"infinity">> ->
+ infinity;
Else ->
parse_ttl(Else)
end.
parse_ttl(Bin) when is_binary(Bin) ->
parse_ttl(binary_to_list(Bin));
+parse_ttl("infinity") ->
+ infinity;
parse_ttl([$- | TTL]) ->
-(parse_ttl(TTL));
parse_ttl(TTL) ->
diff --git a/src/couch/test/eunit/couch_auto_purge_plugin_tests.erl
b/src/couch/test/eunit/couch_auto_purge_plugin_tests.erl
index 38b325022..8e71be0a1 100644
--- a/src/couch/test/eunit/couch_auto_purge_plugin_tests.erl
+++ b/src/couch/test/eunit/couch_auto_purge_plugin_tests.erl
@@ -26,6 +26,9 @@ couch_quickjs_scanner_plugin_test_() ->
?TDEF_FE(t_no_auto_purge_by_default, 10),
?TDEF_FE(t_auto_purge_after_config_ttl, 10),
?TDEF_FE(t_auto_purge_after_db_ttl, 10),
+ ?TDEF_FE(t_no_auto_purge_after_db_ttl_set_to_infinity, 10),
+ ?TDEF_FE(t_no_auto_purge_after_config_ttl_set_to_infinity, 10),
+ ?TDEF_FE(t_db_auto_purge_overrides_cluster_ttl_infinity, 10),
?TDEF_FE(t_min_batch_size_1, 10),
?TDEF_FE(t_min_batch_size_2, 10),
?TDEF_FE(t_max_batch_size_1, 10),
@@ -90,6 +93,41 @@ t_auto_purge_after_db_ttl({_, DbName}) ->
?assertEqual(0, doc_del_count(DbName)),
ok.
+t_no_auto_purge_after_config_ttl_set_to_infinity({_, DbName}) ->
+ config:set(atom_to_list(?PLUGIN), "deleted_document_ttl", "infinity",
false),
+ ok = add_doc(DbName, <<"doc1">>, #{<<"_deleted">> => true}),
+ ?assertEqual(1, doc_del_count(DbName)),
+ meck:reset(couch_scanner_server),
+ meck:reset(?PLUGIN),
+ config:set("couch_scanner_plugins", atom_to_list(?PLUGIN), "true", false),
+ wait_exit(10000),
+ ?assertEqual(1, doc_del_count(DbName)),
+ ok.
+
+t_no_auto_purge_after_db_ttl_set_to_infinity({_, DbName}) ->
+ config:set(atom_to_list(?PLUGIN), "deleted_document_ttl", "-3_hour",
false),
+ ok = fabric:set_auto_purge_props(DbName, [{<<"deleted_document_ttl">>,
<<"infinity">>}]),
+ ok = add_doc(DbName, <<"doc1">>, #{<<"_deleted">> => true}),
+ ?assertEqual(1, doc_del_count(DbName)),
+ meck:reset(couch_scanner_server),
+ meck:reset(?PLUGIN),
+ config:set("couch_scanner_plugins", atom_to_list(?PLUGIN), "true", false),
+ wait_exit(10000),
+ ?assertEqual(1, doc_del_count(DbName)),
+ ok.
+
+t_db_auto_purge_overrides_cluster_ttl_infinity({_, DbName}) ->
+ config:set(atom_to_list(?PLUGIN), "deleted_document_ttl", "infinity",
false),
+ ok = fabric:set_auto_purge_props(DbName, [{<<"deleted_document_ttl">>,
"-3_hour"}]),
+ ok = add_doc(DbName, <<"doc1">>, #{<<"_deleted">> => true}),
+ ?assertEqual(1, doc_del_count(DbName)),
+ meck:reset(couch_scanner_server),
+ meck:reset(?PLUGIN),
+ config:set("couch_scanner_plugins", atom_to_list(?PLUGIN), "true", false),
+ wait_exit(10000),
+ ?assertEqual(0, doc_del_count(DbName)),
+ ok.
+
t_dry_run({_, DbName}) ->
config:set(atom_to_list(?PLUGIN), "dry_run", "true", false),
config:set(atom_to_list(?PLUGIN), "deleted_document_ttl", "-3_hour",
false),
diff --git a/src/docs/src/config/scanner.rst b/src/docs/src/config/scanner.rst
index e03ad7006..cb49acd6f 100644
--- a/src/docs/src/config/scanner.rst
+++ b/src/docs/src/config/scanner.rst
@@ -259,10 +259,13 @@ settings in their ``[{plugin}]`` section.
Set the default interval before the plugin will purge
a deleted document. Possible ttl formats are: ``{num}_{timeunit}``
(ex.:
``1000_sec``, ``30_min``, ``8_hours``, ``24_hour``, ``2_days``,
- ``3_weeks``, ``1_month``).
+ ``3_weeks``, ``1_month``) or ``infinity``.
+
The database may override this setting with the
- :ref:`api/db/auto_purge` endpoint. If neither is set, the
- plugin will not purge deleted documents.
+ :ref:`api/db/auto_purge` endpoint. If neither is set, the plugin will
+ not purge deleted documents. Setting the config value to ``infinity``
+ disables cluster level auto-purge, which may be used to run auto-purge
+ only for specific databases with the database level settings.
.. config:option:: log_level