This is an automated email from the ASF dual-hosted git repository.

vatamane pushed a commit to branch merge-3.4.3
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit 0588c4ac227ab76896ac6e3dd9a368cdafafc276
Author: Nick Vatamaniuc <[email protected]>
AuthorDate: Wed Jan 15 17:35:51 2025 -0500

    Remove idle check timeout
    
    7 years ago we added an idle-check timeout to force idle system shard to 
close
    [1]. It seemed like a relevant setting for Cloudant, where at the time we 
had a
    large number of open `_replicator` dbs per server. However, at Cloudant we 
only
    enabled it once, it failed as it closed too many shards too quickly, and 
then
    they had to be re-opened, which added extra load, we disabled ran with
    `infinity` ever since.
    
    We also never documented it anywhere so let's remove it.
    
    [1] https://github.com/apache/couchdb-couch/pull/236
---
 src/couch/src/couch_bt_engine.erl         |  5 --
 src/couch/src/couch_db_engine.erl         | 14 -----
 src/couch/src/couch_db_updater.erl        | 91 +++++++------------------------
 src/couch/src/couch_file.erl              | 10 ----
 src/couch/test/eunit/couch_file_tests.erl | 10 ----
 5 files changed, 20 insertions(+), 110 deletions(-)

diff --git a/src/couch/src/couch_bt_engine.erl 
b/src/couch/src/couch_bt_engine.erl
index db5df074f..ad84e0db8 100644
--- a/src/couch/src/couch_bt_engine.erl
+++ b/src/couch/src/couch_bt_engine.erl
@@ -30,8 +30,6 @@
     decref/1,
     monitored_by/1,
 
-    last_activity/1,
-
     get_compacted_seq/1,
     get_del_doc_count/1,
     get_disk_version/1,
@@ -212,9 +210,6 @@ monitored_by(St) ->
             []
     end.
 
-last_activity(#st{fd = Fd}) ->
-    couch_file:last_read(Fd).
-
 get_compacted_seq(#st{header = Header}) ->
     couch_bt_engine_header:get(Header, compacted_seq).
 
diff --git a/src/couch/src/couch_db_engine.erl 
b/src/couch/src/couch_db_engine.erl
index 052a527e3..54f2c1482 100644
--- a/src/couch/src/couch_db_engine.erl
+++ b/src/couch/src/couch_db_engine.erl
@@ -180,14 +180,6 @@
 -callback decref(DbHandle :: db_handle()) -> ok.
 -callback monitored_by(DbHande :: db_handle()) -> [pid()].
 
-% This is called in the context of couch_db_updater:handle_info/2
-% and should return the timestamp of the last activity of
-% the database. If a storage has no notion of activity or the
-% value would be hard to report its ok to just return the
-% result of os:timestamp/0 as this will just disable idle
-% databases from automatically closing.
--callback last_activity(DbHandle :: db_handle()) -> erlang:timestamp().
-
 % All of the get_* functions may be called from many
 % processes concurrently.
 
@@ -673,8 +665,6 @@
     decref/1,
     monitored_by/1,
 
-    last_activity/1,
-
     get_engine/1,
     get_compacted_seq/1,
     get_del_doc_count/1,
@@ -791,10 +781,6 @@ monitored_by(#db{} = Db) ->
     #db{engine = {Engine, EngineState}} = Db,
     Engine:monitored_by(EngineState).
 
-last_activity(#db{} = Db) ->
-    #db{engine = {Engine, EngineState}} = Db,
-    Engine:last_activity(EngineState).
-
 get_engine(#db{} = Db) ->
     #db{engine = {Engine, _}} = Db,
     Engine.
diff --git a/src/couch/src/couch_db_updater.erl 
b/src/couch/src/couch_db_updater.erl
index d1b4c1d2d..3f6c8886d 100644
--- a/src/couch/src/couch_db_updater.erl
+++ b/src/couch/src/couch_db_updater.erl
@@ -19,7 +19,6 @@
 -include_lib("couch/include/couch_db.hrl").
 -include("couch_db_int.hrl").
 
--define(IDLE_LIMIT_DEFAULT, 61000).
 % 10 GiB
 -define(DEFAULT_MAX_PARTITION_SIZE, 16#280000000).
 
@@ -34,7 +33,6 @@
 
 init({Engine, DbName, FilePath, Options0}) ->
     erlang:put(io_priority, {db_update, DbName}),
-    update_idle_limit_from_config(),
     DefaultSecObj = default_security_object(DbName),
     Options = [{default_security_object, DefaultSecObj} | Options0],
     try
@@ -51,7 +49,7 @@ init({Engine, DbName, FilePath, Options0}) ->
         % couch_db:validate_doc_update, which loads them lazily.
         NewDb = Db#db{main_pid = self()},
         proc_lib:init_ack({ok, NewDb}),
-        gen_server:enter_loop(?MODULE, [], NewDb, idle_limit())
+        gen_server:enter_loop(?MODULE, [], NewDb)
     catch
         throw:InitError ->
             proc_lib:init_ack(InitError)
@@ -63,39 +61,39 @@ terminate(Reason, Db) ->
     ok.
 
 handle_call(get_db, _From, Db) ->
-    {reply, {ok, Db}, Db, idle_limit()};
+    {reply, {ok, Db}, Db};
 handle_call(start_compact, _From, Db) ->
-    {noreply, NewDb, _Timeout} = handle_cast(start_compact, Db),
-    {reply, {ok, NewDb#db.compactor_pid}, NewDb, idle_limit()};
+    {noreply, NewDb} = handle_cast(start_compact, Db),
+    {reply, {ok, NewDb#db.compactor_pid}, NewDb};
 handle_call(compactor_pid, _From, #db{compactor_pid = Pid} = Db) ->
-    {reply, Pid, Db, idle_limit()};
+    {reply, Pid, Db};
 handle_call(cancel_compact, _From, #db{compactor_pid = nil} = Db) ->
-    {reply, ok, Db, idle_limit()};
+    {reply, ok, Db};
 handle_call(cancel_compact, _From, #db{compactor_pid = Pid} = Db) ->
     unlink(Pid),
     exit(Pid, kill),
     couch_server:delete_compaction_files(Db#db.name),
     Db2 = Db#db{compactor_pid = nil},
     ok = couch_server:db_updated(Db2),
-    {reply, ok, Db2, idle_limit()};
+    {reply, ok, Db2};
 handle_call({set_security, NewSec}, _From, #db{} = Db) ->
     {ok, NewDb} = couch_db_engine:set_security(Db, NewSec),
     NewSecDb = commit_data(NewDb#db{
         security = NewSec
     }),
     ok = couch_server:db_updated(NewSecDb),
-    {reply, ok, NewSecDb, idle_limit()};
+    {reply, ok, NewSecDb};
 handle_call({set_revs_limit, Limit}, _From, Db) ->
     {ok, Db2} = couch_db_engine:set_revs_limit(Db, Limit),
     Db3 = commit_data(Db2),
     ok = couch_server:db_updated(Db3),
-    {reply, ok, Db3, idle_limit()};
+    {reply, ok, Db3};
 handle_call({set_purge_infos_limit, Limit}, _From, Db) ->
     {ok, Db2} = couch_db_engine:set_purge_infos_limit(Db, Limit),
     ok = couch_server:db_updated(Db2),
-    {reply, ok, Db2, idle_limit()};
+    {reply, ok, Db2};
 handle_call({purge_docs, [], _}, _From, Db) ->
-    {reply, {ok, []}, Db, idle_limit()};
+    {reply, {ok, []}, Db};
 handle_call({purge_docs, PurgeReqs0, Options}, _From, Db) ->
     % Filter out any previously applied updates during
     % internal replication
@@ -116,11 +114,11 @@ handle_call({purge_docs, PurgeReqs0, Options}, _From, Db) 
->
                 )
         end,
     {ok, NewDb, Replies} = purge_docs(Db, PurgeReqs),
-    {reply, {ok, Replies}, NewDb, idle_limit()};
+    {reply, {ok, Replies}, NewDb};
 handle_call(Msg, From, Db) ->
     case couch_db_engine:handle_db_updater_call(Msg, From, Db) of
         {reply, Resp, NewDb} ->
-            {reply, Resp, NewDb, idle_limit()};
+            {reply, Resp, NewDb};
         Else ->
             Else
     end.
@@ -128,7 +126,7 @@ handle_call(Msg, From, Db) ->
 handle_cast({load_validation_funs, ValidationFuns}, Db) ->
     Db2 = Db#db{validate_doc_funs = ValidationFuns},
     ok = couch_server:db_updated(Db2),
-    {noreply, Db2, idle_limit()};
+    {noreply, Db2};
 handle_cast(start_compact, Db) ->
     case Db#db.compactor_pid of
         nil ->
@@ -146,16 +144,14 @@ handle_cast(start_compact, Db) ->
             couch_log:Level("Starting compaction for db \"~s\" at ~p", Args),
             {ok, Db2} = couch_db_engine:start_compaction(Db),
             ok = couch_server:db_updated(Db2),
-            {noreply, Db2, idle_limit()};
+            {noreply, Db2};
         _ ->
             % compact currently running, this is a no-op
-            {noreply, Db, idle_limit()}
+            {noreply, Db}
     end;
 handle_cast({compact_done, _Engine, CompactInfo}, #db{} = OldDb) ->
     {ok, NewDb} = couch_db_engine:finish_compaction(OldDb, CompactInfo),
     {noreply, NewDb};
-handle_cast(wakeup, Db) ->
-    {noreply, Db, idle_limit()};
 handle_cast(Msg, #db{name = Name} = Db) ->
     couch_log:error(
         "Database `~s` updater received unexpected cast: ~p",
@@ -213,40 +209,20 @@ handle_info(
                     false ->
                         Db2
                 end,
-            {noreply, Db3, hibernate_if_no_idle_limit()}
+            {noreply, Db3, hibernate}
     catch
         throw:retry ->
             [catch (ClientPid ! {retry, self()}) || ClientPid <- Clients],
-            {noreply, Db, hibernate_if_no_idle_limit()}
+            {noreply, Db, hibernate}
     end;
 handle_info({'EXIT', _Pid, normal}, Db) ->
-    {noreply, Db, idle_limit()};
+    {noreply, Db};
 handle_info({'EXIT', _Pid, Reason}, Db) ->
     {stop, Reason, Db};
-handle_info(timeout, #db{name = DbName} = Db) ->
-    IdleLimitMSec = update_idle_limit_from_config(),
-    case couch_db:is_idle(Db) of
-        true ->
-            LastActivity = couch_db_engine:last_activity(Db),
-            DtMSec = timer:now_diff(os:timestamp(), LastActivity) div 1000,
-            MSecSinceLastActivity = max(0, DtMSec),
-            case MSecSinceLastActivity > IdleLimitMSec of
-                true ->
-                    ok = couch_server:close_db_if_idle(DbName);
-                false ->
-                    ok
-            end;
-        false ->
-            ok
-    end,
-    % Send a message to wake up and then hibernate. Hibernation here is done to
-    % force a thorough garbage collection.
-    gen_server:cast(self(), wakeup),
-    {noreply, Db, hibernate};
 handle_info(Msg, Db) ->
     case couch_db_engine:handle_db_updater_info(Msg, Db) of
         {noreply, NewDb} ->
-            {noreply, NewDb, idle_limit()};
+            {noreply, NewDb};
         Else ->
             Else
     end.
@@ -942,33 +918,6 @@ default_security_object(_DbName) ->
             []
     end.
 
-% These functions rely on using the process dictionary. This is
-% usually frowned upon however in this case it is done to avoid
-% changing to a different server state record. Once PSE (Pluggable
-% Storage Engine) code lands this should be moved to the #db{} record.
-update_idle_limit_from_config() ->
-    Default = integer_to_list(?IDLE_LIMIT_DEFAULT),
-    IdleLimit =
-        case config:get("couchdb", "idle_check_timeout", Default) of
-            "infinity" ->
-                infinity;
-            Milliseconds ->
-                list_to_integer(Milliseconds)
-        end,
-    put(idle_limit, IdleLimit),
-    IdleLimit.
-
-idle_limit() ->
-    get(idle_limit).
-
-hibernate_if_no_idle_limit() ->
-    case idle_limit() of
-        infinity ->
-            hibernate;
-        Timeout when is_integer(Timeout) ->
-            Timeout
-    end.
-
 -ifdef(TEST).
 -include_lib("eunit/include/eunit.hrl").
 
diff --git a/src/couch/src/couch_file.erl b/src/couch/src/couch_file.erl
index 02b2412f3..9c2a7a1d8 100644
--- a/src/couch/src/couch_file.erl
+++ b/src/couch/src/couch_file.erl
@@ -44,7 +44,6 @@
 -export([append_terms/2, append_terms/3]).
 -export([write_header/2, read_header/1]).
 -export([delete/2, delete/3, nuke_dir/2, init_delete_dir/1]).
--export([last_read/1]).
 
 % gen_server callbacks
 -export([init/1, terminate/2, format_status/2]).
@@ -400,16 +399,11 @@ init_status_error(ReturnPid, Ref, Error) ->
     ReturnPid ! {Ref, self(), Error},
     ignore.
 
-last_read(Fd) when is_pid(Fd) ->
-    Now = os:timestamp(),
-    couch_util:process_dict_get(Fd, read_timestamp, Now).
-
 % server functions
 
 init({Filepath, Options, ReturnPid, Ref}) ->
     OpenOptions = file_open_options(Options),
     IsSys = lists:member(sys_db, Options),
-    update_read_timestamp(),
     case lists:member(create, Options) of
         true ->
             filelib:ensure_dir(Filepath),
@@ -489,7 +483,6 @@ terminate(_Reason, #file{fd = Fd}) ->
 handle_call(close, _From, #file{fd = Fd} = File) ->
     {stop, normal, file:close(Fd), File#file{fd = nil}};
 handle_call({pread_iolists, PosL}, _From, File) ->
-    update_read_timestamp(),
     LocNums1 = [{Pos, 4} || Pos <- PosL],
     DataSizes = read_multi_raw_iolists_int(File, LocNums1),
     MapFun = fun({LenIoList, NextPos}) ->
@@ -868,9 +861,6 @@ is_idle(#file{is_sys = false}) ->
 process_info(Pid) ->
     couch_util:process_dict_get(Pid, couch_file_fd).
 
-update_read_timestamp() ->
-    put(read_timestamp, os:timestamp()).
-
 %% in event of a partially successful write.
 reset_eof(#file{} = File) ->
     {ok, Eof} = file:position(File#file.fd, eof),
diff --git a/src/couch/test/eunit/couch_file_tests.erl 
b/src/couch/test/eunit/couch_file_tests.erl
index 36b2a61a1..df4caa714 100644
--- a/src/couch/test/eunit/couch_file_tests.erl
+++ b/src/couch/test/eunit/couch_file_tests.erl
@@ -95,7 +95,6 @@ read_write_test_() ->
                     ?TDEF_FE(should_catch_pread_failure),
                     ?TDEF_FE(should_truncate),
                     ?TDEF_FE(should_set_db_pid),
-                    ?TDEF_FE(should_update_last_read_time),
                     ?TDEF_FE(should_open_read_only),
                     ?TDEF_FE(should_apply_overwrite_create_option),
                     ?TDEF_FE(should_error_on_creation_if_exists),
@@ -245,15 +244,6 @@ should_set_db_pid(Fd) ->
     ),
     ?assertNot(is_process_alive(Fd)).
 
-should_update_last_read_time(Fd) ->
-    {ok, Pos, _} = couch_file:append_term(Fd, foo),
-    ReadTs1 = couch_file:last_read(Fd),
-    ?assertMatch({_, _, _}, ReadTs1),
-    {ok, foo} = couch_file:pread_term(Fd, Pos),
-    ReadTs2 = couch_file:last_read(Fd),
-    ?assertMatch({_, _, _}, ReadTs2),
-    ?assert(ReadTs2 > ReadTs1).
-
 should_open_read_only(Fd) ->
     {_, Path} = couch_file:process_info(Fd),
     {ok, Pos, _} = couch_file:append_term(Fd, foo),

Reply via email to