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 97c8bdc1f Remove idle check timeout
97c8bdc1f is described below
commit 97c8bdc1feb10c13ced09b896d12c268feae96c0
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 7bc02146e..1cd3f6d00 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 8c7370688..46f80f949 100644
--- a/src/couch/src/couch_file.erl
+++ b/src/couch/src/couch_file.erl
@@ -45,7 +45,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]).
@@ -404,16 +403,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),
@@ -493,7 +487,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}) ->
@@ -872,9 +865,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 78db4eb9b..ec024e4bb 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),