You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by da...@apache.org on 2014/02/05 00:06:39 UTC
[26/50] couch commit: updated refs/heads/import to c3116d7
Major change to use the new config app
This replaces couch_config with the config app. The config app is mostly
a direct port of couch_config to a new namespace with the addition of a
rewritten config change notification mechanism. The new change mechanism
removes the ability to register an anonymous function that breaks code
upgrades and generally cleans up the various listening patterns using a
new behavior definition.
Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch/commit/a7d16632
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch/tree/a7d16632
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch/diff/a7d16632
Branch: refs/heads/import
Commit: a7d166329b65f208d69f8be252ef3890a9df5ca0
Parents: 54a7b40
Author: Robert Newson <rn...@apache.org>
Authored: Sat Mar 9 18:22:19 2013 -0600
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Tue Feb 4 17:03:24 2014 -0600
----------------------------------------------------------------------
src/couch.app.tpl.in | 3 +-
src/couch.erl | 8 ---
src/couch_auth_cache.erl | 33 ++++++++----
src/couch_changes.erl | 2 +-
src/couch_compaction_daemon.erl | 32 ++++++++----
src/couch_compress.erl | 2 +-
src/couch_db.erl | 10 ++--
src/couch_db_update_notifier_sup.erl | 19 ++++---
src/couch_db_updater.erl | 12 ++---
src/couch_drv.erl | 2 +-
src/couch_ejson_compare.erl | 2 +-
src/couch_external_manager.erl | 26 +++++++---
src/couch_external_server.erl | 22 ++++++--
src/couch_httpd.erl | 85 +++++++++++--------------------
src/couch_httpd_auth.erl | 28 +++++-----
src/couch_httpd_cors.erl | 6 +--
src/couch_httpd_db.erl | 2 +-
src/couch_httpd_external.erl | 2 +-
src/couch_httpd_misc_handlers.erl | 18 +++----
src/couch_httpd_oauth.erl | 10 ++--
src/couch_httpd_rewrite.erl | 4 +-
src/couch_httpd_vhost.erl | 38 +++++++++-----
src/couch_log.erl | 51 +++++++++++--------
src/couch_os_daemons.erl | 33 ++++++++----
src/couch_os_process.erl | 4 +-
src/couch_passwords.erl | 4 +-
src/couch_proc_manager.erl | 6 +--
src/couch_secondary_sup.erl | 2 +-
src/couch_server.erl | 56 +++++++++++++-------
src/couch_server_sup.erl | 53 ++++++++-----------
src/couch_stats_aggregator.erl | 27 +++++++---
src/couch_users_db.erl | 2 +-
src/couch_uuids.erl | 23 +++++++--
33 files changed, 361 insertions(+), 266 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/a7d16632/src/couch.app.tpl.in
----------------------------------------------------------------------
diff --git a/src/couch.app.tpl.in b/src/couch.app.tpl.in
index f83b6f6..1cd0154 100644
--- a/src/couch.app.tpl.in
+++ b/src/couch.app.tpl.in
@@ -3,7 +3,6 @@
{vsn, "@version@"},
{modules, [@modules@]},
{registered, [
- couch_config,
couch_db_update,
couch_db_update_notifier_sup,
couch_external_manager,
@@ -22,6 +21,6 @@
"%localconfdir%/@defaultini@",
"%localconfdir%/@localini@"
]}},
- {applications, [kernel, stdlib, twig]},
+ {applications, [kernel, stdlib, twig, config]},
{included_applications, [crypto, sasl, inets, oauth, ibrowse, mochiweb, os_mon]}
]}.
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/a7d16632/src/couch.erl
----------------------------------------------------------------------
diff --git a/src/couch.erl b/src/couch.erl
index c18df0b..7d53d0c 100644
--- a/src/couch.erl
+++ b/src/couch.erl
@@ -29,11 +29,3 @@ restart() ->
{error, Reason} ->
{error, Reason}
end.
-
-reload() ->
- case supervisor:terminate_child(couch_server_sup, couch_config) of
- ok ->
- supervisor:restart_child(couch_server_sup, couch_config);
- {error, Reason} ->
- {error, Reason}
- end.
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/a7d16632/src/couch_auth_cache.erl
----------------------------------------------------------------------
diff --git a/src/couch_auth_cache.erl b/src/couch_auth_cache.erl
index 5f4c8f9..1650495 100644
--- a/src/couch_auth_cache.erl
+++ b/src/couch_auth_cache.erl
@@ -12,6 +12,7 @@
-module(couch_auth_cache).
-behaviour(gen_server).
+-behaviour(config_listener).
% public API
-export([get_user_creds/1]).
@@ -20,6 +21,8 @@
-export([start_link/0, init/1, handle_call/3, handle_info/2, handle_cast/2]).
-export([code_change/3, terminate/2]).
+-export([handle_config_change/5]).
+
-include_lib("couch/include/couch_db.hrl").
-include("couch_js_functions.hrl").
@@ -42,7 +45,7 @@ get_user_creds(UserName) when is_list(UserName) ->
get_user_creds(?l2b(UserName));
get_user_creds(UserName) ->
- UserCreds = case couch_config:get("admins", ?b2l(UserName)) of
+ UserCreds = case config:get("admins", ?b2l(UserName)) of
"-hashed-" ++ HashedPwdAndSalt ->
% the name is an admin, now check to see if there is a user doc
% which has a matching name, salt, and password_sha
@@ -120,19 +123,12 @@ init(_) ->
?BY_USER = ets:new(?BY_USER, [set, protected, named_table]),
?BY_ATIME = ets:new(?BY_ATIME, [ordered_set, private, named_table]),
process_flag(trap_exit, true),
- ok = couch_config:register(
- fun("couch_httpd_auth", "auth_cache_size", SizeList) ->
- Size = list_to_integer(SizeList),
- ok = gen_server:call(?MODULE, {new_max_cache_size, Size}, infinity);
- ("couch_httpd_auth", "authentication_db", _DbName) ->
- ok = gen_server:call(?MODULE, reinit_cache, infinity)
- end
- ),
+ ok = config:listen_for_changes(?MODULE, nil),
{ok, Notifier} = couch_db_update_notifier:start_link(fun handle_db_event/1),
State = #state{
db_notifier = Notifier,
max_cache_size = list_to_integer(
- couch_config:get("couch_httpd_auth", "auth_cache_size", "50")
+ config:get("couch_httpd_auth", "auth_cache_size", "50")
)
},
{ok, reinit_cache(State)}.
@@ -201,6 +197,12 @@ handle_cast({cache_hit, UserName}, State) ->
{noreply, State}.
+handle_info({gen_event_EXIT, {config_listener, ?MODULE}, _Reason}, State) ->
+ erlang:send_after(5000, self(), restart_config_listener),
+ {noreply, State};
+handle_info(restart_config_listener, State) ->
+ ok = config:listen_for_changes(?MODULE, nil),
+ {noreply, State};
handle_info({'DOWN', Ref, _, _, _Reason}, #state{db_mon_ref = Ref} = State) ->
{noreply, reinit_cache(State)}.
@@ -217,6 +219,15 @@ code_change(_OldVsn, State, _Extra) ->
{ok, State}.
+handle_config_change("couch_httpd_auth", "auth_cache_size", SizeList, _, _) ->
+ Size = list_to_integer(SizeList),
+ {ok, gen_server:call(?MODULE, {new_max_cache_size, Size}, infinity)};
+handle_config_change("couch_httpd_auth", "authentication_db", _DbName, _, _) ->
+ {ok, gen_server:call(?MODULE, reinit_cache, infinity)};
+handle_config_change(_, _, _, _, _) ->
+ {ok, nil}.
+
+
clear_cache(State) ->
exec_if_auth_db(fun(AuthDb) -> catch couch_db:close(AuthDb) end),
true = ets:delete_all_objects(?BY_USER),
@@ -226,7 +237,7 @@ clear_cache(State) ->
reinit_cache(State) ->
NewState = clear_cache(State),
- AuthDbName = ?l2b(couch_config:get("couch_httpd_auth", "authentication_db")),
+ AuthDbName = ?l2b(config:get("couch_httpd_auth", "authentication_db")),
true = ets:insert(?STATE, {auth_db_name, AuthDbName}),
AuthDb = open_auth_db(),
true = ets:insert(?STATE, {auth_db, AuthDb}),
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/a7d16632/src/couch_changes.erl
----------------------------------------------------------------------
diff --git a/src/couch_changes.erl b/src/couch_changes.erl
index cbca9cb..d36b45f 100644
--- a/src/couch_changes.erl
+++ b/src/couch_changes.erl
@@ -258,7 +258,7 @@ get_changes_timeout(Args, Callback) ->
feed = ResponseType
} = Args,
DefaultTimeout = list_to_integer(
- couch_config:get("httpd", "changes_timeout", "60000")
+ config:get("httpd", "changes_timeout", "60000")
),
case Heartbeat of
undefined ->
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/a7d16632/src/couch_compaction_daemon.erl
----------------------------------------------------------------------
diff --git a/src/couch_compaction_daemon.erl b/src/couch_compaction_daemon.erl
index b9bf969..3251d5f 100644
--- a/src/couch_compaction_daemon.erl
+++ b/src/couch_compaction_daemon.erl
@@ -12,14 +12,18 @@
-module(couch_compaction_daemon).
-behaviour(gen_server).
+-behaviour(config_listener).
% public API
--export([start_link/0, config_change/3]).
+-export([start_link/0]).
% gen_server callbacks
-export([init/1, handle_call/3, handle_info/2, handle_cast/2]).
-export([code_change/3, terminate/2]).
+% config_listener api
+-export([handle_config_change/5]).
+
-include_lib("couch/include/couch_db.hrl").
-define(CONFIG_ETS, couch_compaction_daemon_config).
@@ -49,17 +53,13 @@ start_link() ->
init(_) ->
process_flag(trap_exit, true),
?CONFIG_ETS = ets:new(?CONFIG_ETS, [named_table, set, protected]),
- ok = couch_config:register(fun ?MODULE:config_change/3),
+ ok = config:listen_for_changes(?MODULE, nil),
load_config(),
Server = self(),
Loop = spawn_link(fun() -> compact_loop(Server) end),
{ok, #state{loop_pid = Loop}}.
-config_change("compactions", DbName, NewValue) ->
- ok = gen_server:cast(?MODULE, {config_update, DbName, NewValue}).
-
-
handle_cast({config_update, DbName, deleted}, State) ->
true = ets:delete(?CONFIG_ETS, ?l2b(DbName)),
{noreply, State};
@@ -85,6 +85,12 @@ handle_call(Msg, _From, State) ->
{stop, {unexpected_call, Msg}, State}.
+handle_info({gen_event_EXIT, {config_listener, ?MODULE}, _Reason}, State) ->
+ erlang:send_after(5000, self(), restart_config_listener),
+ {noreply, State};
+handle_info(restart_config_listener, State) ->
+ ok = config:listen_for_changes(?MODULE, nil),
+ {noreply, State};
handle_info({'EXIT', Pid, Reason}, #state{loop_pid = Pid} = State) ->
{stop, {compaction_loop_died, Reason}, State}.
@@ -97,6 +103,12 @@ code_change(_OldVsn, State, _Extra) ->
{ok, State}.
+handle_config_change("compactions", DbName, Value, _, _) ->
+ {ok, gen_server:cast(?MODULE, {config_update, DbName, Value})};
+handle_config_change(_, _, _, _, _) ->
+ {ok, nil}.
+
+
compact_loop(Parent) ->
{ok, _} = couch_server:all_databases(
fun(DbName, Acc) ->
@@ -123,7 +135,7 @@ compact_loop(Parent) ->
receive {Parent, have_config} -> ok end;
false ->
PausePeriod = list_to_integer(
- couch_config:get("compaction_daemon", "check_interval", "300")),
+ config:get("compaction_daemon", "check_interval", "300")),
ok = timer:sleep(PausePeriod * 1000)
end,
compact_loop(Parent).
@@ -295,7 +307,7 @@ can_db_compact(#config{db_frag = Threshold} = Config, Db) ->
false ->
false;
true ->
- Free = free_space(couch_config:get("couchdb", "database_dir")),
+ Free = free_space(config:get("couchdb", "database_dir")),
case Free >= SpaceRequired of
true ->
true;
@@ -364,7 +376,7 @@ check_frag(Threshold, Frag) ->
frag(Props) ->
FileSize = couch_util:get_value(disk_size, Props),
MinFileSize = list_to_integer(
- couch_config:get("compaction_daemon", "min_file_size", "131072")),
+ config:get("compaction_daemon", "min_file_size", "131072")),
case FileSize < MinFileSize of
true ->
{0, FileSize};
@@ -396,7 +408,7 @@ load_config() ->
ok
end
end,
- couch_config:get("compactions")).
+ config:get("compactions")).
parse_config(DbName, ConfigString) ->
case (catch do_parse_config(ConfigString)) of
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/a7d16632/src/couch_compress.erl
----------------------------------------------------------------------
diff --git a/src/couch_compress.erl b/src/couch_compress.erl
index 0b9334a..6b47a7a 100644
--- a/src/couch_compress.erl
+++ b/src/couch_compress.erl
@@ -26,7 +26,7 @@
get_compression_method() ->
- case couch_config:get("couchdb", "file_compression") of
+ case config:get("couchdb", "file_compression") of
undefined ->
?DEFAULT_COMPRESSION;
Method1 ->
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/a7d16632/src/couch_db.erl
----------------------------------------------------------------------
diff --git a/src/couch_db.erl b/src/couch_db.erl
index 5f91633..56cb0d2 100644
--- a/src/couch_db.erl
+++ b/src/couch_db.erl
@@ -893,7 +893,7 @@ make_first_doc_on_disk(Db, Id, Pos, [{_Rev, RevValue} |_]=DocPath) ->
set_commit_option(Options) ->
CommitSettings = {
[true || O <- Options, O==full_commit orelse O==delay_commit],
- couch_config:get("couchdb", "delayed_commits", "false")
+ config:get("couchdb", "delayed_commits", "false")
},
case CommitSettings of
{[true], _} ->
@@ -1016,7 +1016,7 @@ flush_att(Fd, #att{data=Data}=Att) when is_binary(Data) ->
flush_att(Fd, #att{data=Fun,att_len=undefined}=Att) when is_function(Fun) ->
MaxChunkSize = list_to_integer(
- couch_config:get("couchdb", "attachment_stream_buffer_size", "4096")),
+ config:get("couchdb", "attachment_stream_buffer_size", "4096")),
with_stream(Fd, Att, fun(OutputStream) ->
% Fun(MaxChunkSize, WriterFun) must call WriterFun
% once for each chunk of the attachment,
@@ -1067,7 +1067,7 @@ compressible_att_type(MimeType) when is_binary(MimeType) ->
compressible_att_type(?b2l(MimeType));
compressible_att_type(MimeType) ->
TypeExpList = re:split(
- couch_config:get("attachments", "compressible_types", ""),
+ config:get("attachments", "compressible_types", ""),
"\\s*,\\s*",
[{return, list}]
),
@@ -1092,12 +1092,12 @@ compressible_att_type(MimeType) ->
% pretend that no Content-MD5 exists.
with_stream(Fd, #att{md5=InMd5,type=Type,encoding=Enc}=Att, Fun) ->
BufferSize = list_to_integer(
- couch_config:get("couchdb", "attachment_stream_buffer_size", "4096")),
+ config:get("couchdb", "attachment_stream_buffer_size", "4096")),
{ok, OutputStream} = case (Enc =:= identity) andalso
compressible_att_type(Type) of
true ->
CompLevel = list_to_integer(
- couch_config:get("attachments", "compression_level", "0")
+ config:get("attachments", "compression_level", "0")
),
couch_stream:open(Fd, [{buffer_size, BufferSize},
{encoding, gzip}, {compression_level, CompLevel}]);
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/a7d16632/src/couch_db_update_notifier_sup.erl
----------------------------------------------------------------------
diff --git a/src/couch_db_update_notifier_sup.erl b/src/couch_db_update_notifier_sup.erl
index e7cc16c..9eb943a 100644
--- a/src/couch_db_update_notifier_sup.erl
+++ b/src/couch_db_update_notifier_sup.erl
@@ -21,17 +21,22 @@
-module(couch_db_update_notifier_sup).
-behaviour(supervisor).
+-behaviour(config_listener).
+
+-export([start_link/0, init/1]).
+
+% config_listener api
+-export([handle_config_change/5]).
--export([start_link/0, init/1, config_change/3]).
start_link() ->
supervisor:start_link({local, couch_db_update_notifier_sup},
couch_db_update_notifier_sup, []).
init([]) ->
- ok = couch_config:register(fun ?MODULE:config_change/3),
+ ok = config:listen_for_changes(?MODULE, nil),
- UpdateNotifierExes = couch_config:get("update_notification"),
+ UpdateNotifierExes = config:get("update_notification"),
{ok,
{{one_for_one, 10, 3600},
@@ -46,7 +51,7 @@ init([]) ->
%% @doc when update_notification configuration changes, terminate the process
%% for that notifier and start a new one with the updated config
-config_change("update_notification", Id, Exe) ->
+handle_config_change("update_notification", Id, Exe, _, _) ->
ChildSpec = {
Id,
{couch_db_update_notifier, start_link, [Exe]},
@@ -57,5 +62,7 @@ config_change("update_notification", Id, Exe) ->
},
supervisor:terminate_child(couch_db_update_notifier_sup, Id),
supervisor:delete_child(couch_db_update_notifier_sup, Id),
- supervisor:start_child(couch_db_update_notifier_sup, ChildSpec).
-
+ supervisor:start_child(couch_db_update_notifier_sup, ChildSpec),
+ {ok, nil};
+handle_config_change(_, _, _, _, _) ->
+ {ok, nil}.
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/a7d16632/src/couch_db_updater.erl
----------------------------------------------------------------------
diff --git a/src/couch_db_updater.erl b/src/couch_db_updater.erl
index e1dc7c3..c64911e 100644
--- a/src/couch_db_updater.erl
+++ b/src/couch_db_updater.erl
@@ -40,7 +40,7 @@ init({DbName, Filepath, Fd, Options}) ->
Header = #db_header{},
ok = couch_file:write_header(Fd, Header),
% delete any old compaction files that might be hanging around
- RootDir = couch_config:get("couchdb", "database_dir", "."),
+ RootDir = config:get("couchdb", "database_dir", "."),
couch_file:delete(RootDir, Filepath ++ ".compact"),
couch_file:delete(RootDir, Filepath ++ ".compact.data"),
couch_file:delete(RootDir, Filepath ++ ".compact.meta");
@@ -92,7 +92,7 @@ handle_call(cancel_compact, _From, #db{compactor_pid = nil} = Db) ->
handle_call(cancel_compact, _From, #db{compactor_pid = Pid} = Db) ->
unlink(Pid),
exit(Pid, kill),
- RootDir = couch_config:get("couchdb", "database_dir", "."),
+ RootDir = config:get("couchdb", "database_dir", "."),
ok = couch_file:delete(RootDir, Db#db.filepath ++ ".compact"),
Db2 = Db#db{compactor_pid = nil},
ok = gen_server:call(couch_server, {db_updated, Db2}, infinity),
@@ -228,7 +228,7 @@ handle_cast({compact_done, CompactFilepath}, #db{filepath=Filepath}=Db) ->
?LOG_DEBUG("CouchDB swapping files ~s and ~s.",
[Filepath, CompactFilepath]),
ok = file:rename(CompactFilepath, Filepath ++ ".compact"),
- RootDir = couch_config:get("couchdb", "database_dir", "."),
+ RootDir = config:get("couchdb", "database_dir", "."),
couch_file:delete(RootDir, Filepath),
ok = file:rename(Filepath ++ ".compact", Filepath),
% Delete the old meta compaction file after promoting
@@ -461,7 +461,7 @@ init_db(DbName, Filepath, Fd, Header0, Options) ->
end,
{ok, FsyncOptions} = couch_util:parse_term(
- couch_config:get("couchdb", "fsync_options",
+ config:get("couchdb", "fsync_options",
"[before_header, after_header, on_file_open]")),
case lists:member(on_file_open, FsyncOptions) of
@@ -946,9 +946,9 @@ copy_compact(Db, NewDb0, Retry) ->
NewDb = NewDb0#db{compression=Compression},
TotalChanges = couch_db:count_changes_since(Db, NewDb#db.update_seq),
BufferSize = list_to_integer(
- couch_config:get("database_compaction", "doc_buffer_size", "524288")),
+ config:get("database_compaction", "doc_buffer_size", "524288")),
CheckpointAfter = couch_util:to_integer(
- couch_config:get("database_compaction", "checkpoint_after",
+ config:get("database_compaction", "checkpoint_after",
BufferSize * 10)),
EnumBySeqFun =
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/a7d16632/src/couch_drv.erl
----------------------------------------------------------------------
diff --git a/src/couch_drv.erl b/src/couch_drv.erl
index de4d76e..7fe119a 100644
--- a/src/couch_drv.erl
+++ b/src/couch_drv.erl
@@ -54,7 +54,7 @@ code_change(_OldVsn, State, _Extra) ->
% private API
util_driver_dir() ->
- case couch_config:get("couchdb", "util_driver_dir", null) of
+ case config:get("couchdb", "util_driver_dir", null) of
null ->
couch_util:priv_dir();
LibDir0 ->
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/a7d16632/src/couch_ejson_compare.erl
----------------------------------------------------------------------
diff --git a/src/couch_ejson_compare.erl b/src/couch_ejson_compare.erl
index 083ff42..7b000fc 100644
--- a/src/couch_ejson_compare.erl
+++ b/src/couch_ejson_compare.erl
@@ -18,7 +18,7 @@
init() ->
- LibDir = case couch_config:get("couchdb", "util_driver_dir") of
+ LibDir = case config:get("couchdb", "util_driver_dir") of
undefined ->
filename:join(couch_util:priv_dir(), "lib");
LibDir0 ->
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/a7d16632/src/couch_external_manager.erl
----------------------------------------------------------------------
diff --git a/src/couch_external_manager.erl b/src/couch_external_manager.erl
index dec2880..a8cad63 100644
--- a/src/couch_external_manager.erl
+++ b/src/couch_external_manager.erl
@@ -12,10 +12,14 @@
-module(couch_external_manager).
-behaviour(gen_server).
+-behaviour(config_listener).
--export([start_link/0, execute/2, config_change/2]).
+-export([start_link/0, execute/2]).
-export([init/1, terminate/2, code_change/3, handle_call/3, handle_cast/2, handle_info/2]).
+% config_listener api
+-export([handle_config_change/5]).
+
-include_lib("couch/include/couch_db.hrl").
start_link() ->
@@ -31,15 +35,17 @@ execute(UrlName, JsonReq) ->
couch_external_server:execute(Pid, JsonReq)
end.
-config_change("external", UrlName) ->
- gen_server:call(couch_external_manager, {config, UrlName}).
+handle_config_change("external", UrlName, _, _, _) ->
+ {ok, gen_server:call(couch_external_manager, {config, UrlName})};
+handle_config_change(_, _, _, _, _) ->
+ {ok, nil}.
% gen_server API
init([]) ->
process_flag(trap_exit, true),
Handlers = ets:new(couch_external_manager_handlers, [set, private]),
- couch_config:register(fun ?MODULE:config_change/2),
+ ok = config:listen_for_changes(?MODULE, nil),
{ok, Handlers}.
terminate(_Reason, Handlers) ->
@@ -52,7 +58,7 @@ terminate(_Reason, Handlers) ->
handle_call({get, UrlName}, _From, Handlers) ->
case ets:lookup(Handlers, UrlName) of
[] ->
- case couch_config:get("external", UrlName, nil) of
+ case config:get("external", UrlName, nil) of
nil ->
Msg = lists:flatten(
io_lib:format("No server configured for ~p.", [UrlName])),
@@ -94,7 +100,15 @@ handle_info({'EXIT', Pid, Reason}, Handlers) ->
% Remove Pid from the handlers table so we don't try closing
% it a second time in terminate/2.
ets:match_delete(Handlers, {'_', Pid}),
- {stop, normal, Handlers}.
+ {stop, normal, Handlers};
+
+handle_info({gen_event_EXIT, {config_listener, ?MODULE}, _Reason}, State) ->
+ erlang:send_after(5000, self(), restart_config_listener),
+ {noreply, State};
+
+handle_info(restart_config_listener, State) ->
+ ok = config:listen_for_changes(?MODULE, nil),
+ {noreply, State}.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/a7d16632/src/couch_external_server.erl
----------------------------------------------------------------------
diff --git a/src/couch_external_server.erl b/src/couch_external_server.erl
index a3924d0..56406bb 100644
--- a/src/couch_external_server.erl
+++ b/src/couch_external_server.erl
@@ -12,10 +12,14 @@
-module(couch_external_server).
-behaviour(gen_server).
+-behaviour(config_listener).
-export([start_link/2, stop/1, execute/2]).
-export([init/1, terminate/2, handle_call/3, handle_cast/2, handle_info/2, code_change/3]).
+% config_listener api
+-export([handle_config_change/5]).
+
-include_lib("couch/include/couch_db.hrl").
% External API
@@ -36,12 +40,10 @@ init([Name, Command]) ->
?LOG_INFO("EXTERNAL: Starting process for: ~s", [Name]),
?LOG_INFO("COMMAND: ~s", [Command]),
process_flag(trap_exit, true),
- Timeout = list_to_integer(couch_config:get("couchdb", "os_process_timeout",
+ Timeout = list_to_integer(config:get("couchdb", "os_process_timeout",
"5000")),
{ok, Pid} = couch_os_process:start_link(Command, [{timeout, Timeout}]),
- couch_config:register(fun("couchdb", "os_process_timeout", NewTimeout) ->
- couch_os_process:set_timeout(Pid, list_to_integer(NewTimeout))
- end),
+ ok = config:listen_for_changes(?MODULE, {Name, Command, Pid}, Pid),
{ok, {Name, Command, Pid}}.
terminate(_Reason, {_Name, _Command, Pid}) ->
@@ -51,6 +53,12 @@ terminate(_Reason, {_Name, _Command, Pid}) ->
handle_call({execute, JsonReq}, _From, {Name, Command, Pid}) ->
{reply, couch_os_process:prompt(Pid, JsonReq), {Name, Command, Pid}}.
+handle_info({gen_event_EXIT, {config_listener, ?MODULE}, _Reason}, State) ->
+ erlang:send_after(5000, self(), restart_config_listener),
+ {noreply, State};
+handle_info(restart_config_listener, State) ->
+ ok = config:listen_for_changes(?MODULE, State),
+ {noreply, State};
handle_info({'EXIT', _Pid, normal}, State) ->
{noreply, State};
handle_info({'EXIT', Pid, Reason}, {Name, Command, Pid}) ->
@@ -68,3 +76,9 @@ code_change(_OldVsn, State, _Extra) ->
{ok, State}.
+handle_config_change("couchdb", "os_process_timeout", NewTimeout, _, Pid) ->
+ couch_os_process:set_timeout(Pid, list_to_integer(NewTimeout)),
+ {ok, Pid};
+handle_config_change(_, _, _, _, Pid) ->
+ {ok, Pid}.
+
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/a7d16632/src/couch_httpd.erl
----------------------------------------------------------------------
diff --git a/src/couch_httpd.erl b/src/couch_httpd.erl
index 53ae47e..db90129 100644
--- a/src/couch_httpd.erl
+++ b/src/couch_httpd.erl
@@ -13,8 +13,7 @@
-module(couch_httpd).
-include_lib("couch/include/couch_db.hrl").
--export([start_link/0, start_link/1, stop/0, config_change/2,
- handle_request/5]).
+-export([start_link/0, start_link/1, stop/0, handle_request/5]).
-export([header_value/2,header_value/3,qs_value/2,qs_value/3,qs/1,qs_json_value/3]).
-export([path/1,absolute_uri/2,body_length/1]).
@@ -35,28 +34,28 @@
start_link() ->
start_link(http).
start_link(http) ->
- Port = couch_config:get("httpd", "port", "5984"),
+ Port = config:get("httpd", "port", "5984"),
start_link(?MODULE, [{port, Port}]);
start_link(https) ->
- Port = couch_config:get("ssl", "port", "6984"),
- CertFile = couch_config:get("ssl", "cert_file", nil),
- KeyFile = couch_config:get("ssl", "key_file", nil),
+ Port = config:get("ssl", "port", "6984"),
+ CertFile = config:get("ssl", "cert_file", nil),
+ KeyFile = config:get("ssl", "key_file", nil),
Options = case CertFile /= nil andalso KeyFile /= nil of
true ->
SslOpts = [{certfile, CertFile}, {keyfile, KeyFile}],
%% set password if one is needed for the cert
- SslOpts1 = case couch_config:get("ssl", "password", nil) of
+ SslOpts1 = case config:get("ssl", "password", nil) of
nil -> SslOpts;
Password ->
SslOpts ++ [{password, Password}]
end,
% do we verify certificates ?
- FinalSslOpts = case couch_config:get("ssl",
+ FinalSslOpts = case config:get("ssl",
"verify_ssl_certificates", "false") of
"false" -> SslOpts1;
"true" ->
- case couch_config:get("ssl",
+ case config:get("ssl",
"cacert_file", nil) of
nil ->
io:format("Verify SSL certificate "
@@ -65,7 +64,7 @@ start_link(https) ->
++"missing", []),
throw({error, missing_cacerts});
CaCertFile ->
- Depth = list_to_integer(couch_config:get("ssl",
+ Depth = list_to_integer(config:get("ssl",
"ssl_certificate_max_depth",
"1")),
FinalOpts = [
@@ -73,7 +72,7 @@ start_link(https) ->
{depth, Depth},
{verify, verify_peer}],
% allows custom verify fun.
- case couch_config:get("ssl",
+ case config:get("ssl",
"verify_fun", nil) of
nil -> FinalOpts;
SpecStr ->
@@ -92,40 +91,35 @@ start_link(https) ->
end,
start_link(https, Options).
start_link(Name, Options) ->
- % read config and register for configuration changes
-
- % just stop if one of the config settings change. couch_server_sup
- % will restart us and then we will pick up the new settings.
-
- BindAddress = couch_config:get("httpd", "bind_address", any),
+ BindAddress = config:get("httpd", "bind_address", any),
validate_bind_address(BindAddress),
DefaultSpec = "{couch_httpd_db, handle_request}",
DefaultFun = make_arity_1_fun(
- couch_config:get("httpd", "default_handler", DefaultSpec)
+ config:get("httpd", "default_handler", DefaultSpec)
),
UrlHandlersList = lists:map(
fun({UrlKey, SpecStr}) ->
{?l2b(UrlKey), make_arity_1_fun(SpecStr)}
- end, couch_config:get("httpd_global_handlers")),
+ end, config:get("httpd_global_handlers")),
DbUrlHandlersList = lists:map(
fun({UrlKey, SpecStr}) ->
{?l2b(UrlKey), make_arity_2_fun(SpecStr)}
- end, couch_config:get("httpd_db_handlers")),
+ end, config:get("httpd_db_handlers")),
DesignUrlHandlersList = lists:map(
fun({UrlKey, SpecStr}) ->
{?l2b(UrlKey), make_arity_3_fun(SpecStr)}
- end, couch_config:get("httpd_design_handlers")),
+ end, config:get("httpd_design_handlers")),
UrlHandlers = dict:from_list(UrlHandlersList),
DbUrlHandlers = dict:from_list(DbUrlHandlersList),
DesignUrlHandlers = dict:from_list(DesignUrlHandlersList),
{ok, ServerOptions} = couch_util:parse_term(
- couch_config:get("httpd", "server_options", "[]")),
+ config:get("httpd", "server_options", "[]")),
{ok, SocketOptions} = couch_util:parse_term(
- couch_config:get("httpd", "socket_options", "[]")),
+ config:get("httpd", "socket_options", "[]")),
set_auth_handlers(),
@@ -152,44 +146,23 @@ start_link(Name, Options) ->
{ip, BindAddress}]]),
% launch mochiweb
- {ok, Pid} = case mochiweb_http:start(FinalOptions) of
+ case mochiweb_http:start(FinalOptions) of
{ok, MochiPid} ->
{ok, MochiPid};
{error, Reason} ->
io:format("Failure to start Mochiweb: ~s~n",[Reason]),
throw({error, Reason})
- end,
-
- ok = couch_config:register(fun ?MODULE:config_change/2, Pid),
- {ok, Pid}.
+ end.
stop() ->
mochiweb_http:stop(couch_httpd),
mochiweb_http:stop(https).
-config_change("httpd", "bind_address") ->
- ?MODULE:stop();
-config_change("httpd", "port") ->
- ?MODULE:stop();
-config_change("httpd", "default_handler") ->
- ?MODULE:stop();
-config_change("httpd", "server_options") ->
- ?MODULE:stop();
-config_change("httpd", "socket_options") ->
- ?MODULE:stop();
-config_change("httpd", "authentication_handlers") ->
- set_auth_handlers();
-config_change("httpd_global_handlers", _) ->
- ?MODULE:stop();
-config_change("httpd_db_handlers", _) ->
- ?MODULE:stop();
-config_change("ssl", _) ->
- ?MODULE:stop().
set_auth_handlers() ->
AuthenticationSrcs = make_fun_spec_strs(
- couch_config:get("httpd", "authentication_handlers", "")),
+ config:get("httpd", "authentication_handlers", "")),
AuthHandlers = lists:map(
fun(A) -> {make_arity_1_fun(A), ?l2b(A)} end, AuthenticationSrcs),
ok = application:set_env(couch, auth_handlers, AuthHandlers).
@@ -387,7 +360,7 @@ handle_request_int(MochiReq, DefaultFun,
authenticate_request(#httpd{user_ctx=#user_ctx{}} = Req, _AuthHandlers) ->
Req;
authenticate_request(#httpd{} = Req, []) ->
- case couch_config:get("couch_httpd_auth", "require_valid_user", "false") of
+ case config:get("couch_httpd_auth", "require_valid_user", "false") of
"true" ->
throw({unauthorized, <<"Authentication required.">>});
"false" ->
@@ -493,7 +466,7 @@ path(#httpd{mochi_req=MochiReq}) ->
MochiReq:get(path).
host_for_request(#httpd{mochi_req=MochiReq}) ->
- XHost = couch_config:get("httpd", "x_forwarded_host", "X-Forwarded-Host"),
+ XHost = config:get("httpd", "x_forwarded_host", "X-Forwarded-Host"),
case MochiReq:get_header_value(XHost) of
undefined ->
case MochiReq:get_header_value("Host") of
@@ -511,11 +484,11 @@ host_for_request(#httpd{mochi_req=MochiReq}) ->
absolute_uri(#httpd{mochi_req=MochiReq}=Req, Path) ->
Host = host_for_request(Req),
- XSsl = couch_config:get("httpd", "x_forwarded_ssl", "X-Forwarded-Ssl"),
+ XSsl = config:get("httpd", "x_forwarded_ssl", "X-Forwarded-Ssl"),
Scheme = case MochiReq:get_header_value(XSsl) of
"on" -> "https";
_ ->
- XProto = couch_config:get("httpd", "x_forwarded_proto", "X-Forwarded-Proto"),
+ XProto = config:get("httpd", "x_forwarded_proto", "X-Forwarded-Proto"),
case MochiReq:get_header_value(XProto) of
%% Restrict to "https" and "http" schemes only
"https" -> "https";
@@ -550,7 +523,7 @@ body_length(#httpd{mochi_req=MochiReq}) ->
body(#httpd{mochi_req=MochiReq, req_body=undefined}) ->
MaxSize = list_to_integer(
- couch_config:get("couchdb", "max_document_size", "4294967296")),
+ config:get("couchdb", "max_document_size", "4294967296")),
MochiReq:recv_body(MaxSize);
body(#httpd{req_body=ReqBody}) ->
ReqBody.
@@ -753,7 +726,7 @@ initialize_jsonp(Req) ->
CallBack ->
try
% make sure jsonp is configured on (default off)
- case couch_config:get("httpd", "allow_jsonp", "false") of
+ case config:get("httpd", "allow_jsonp", "false") of
"true" ->
validate_callback(CallBack);
_Else ->
@@ -848,16 +821,16 @@ error_headers(#httpd{mochi_req=MochiReq}=Req, Code, ErrorStr, ReasonStr) ->
% this is where the basic auth popup is triggered
case MochiReq:get_header_value("X-CouchDB-WWW-Authenticate") of
undefined ->
- case couch_config:get("httpd", "WWW-Authenticate", nil) of
+ case config:get("httpd", "WWW-Authenticate", nil) of
nil ->
% If the client is a browser and the basic auth popup isn't turned on
% redirect to the session page.
case ErrorStr of
<<"unauthorized">> ->
- case couch_config:get("couch_httpd_auth", "authentication_redirect", nil) of
+ case config:get("couch_httpd_auth", "authentication_redirect", nil) of
nil -> {Code, []};
AuthRedirect ->
- case couch_config:get("couch_httpd_auth", "require_valid_user", "false") of
+ case config:get("couch_httpd_auth", "require_valid_user", "false") of
"true" ->
% send the browser popup header no matter what if we are require_valid_user
{Code, [{"WWW-Authenticate", "Basic realm=\"server\""}]};
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/a7d16632/src/couch_httpd_auth.erl
----------------------------------------------------------------------
diff --git a/src/couch_httpd_auth.erl b/src/couch_httpd_auth.erl
index 785dd79..a747869 100644
--- a/src/couch_httpd_auth.erl
+++ b/src/couch_httpd_auth.erl
@@ -83,7 +83,7 @@ default_authentication_handler(Req) ->
true ->
Req;
false ->
- case couch_config:get("couch_httpd_auth", "require_valid_user", "false") of
+ case config:get("couch_httpd_auth", "require_valid_user", "false") of
"true" -> Req;
% If no admins, and no user required, then everyone is admin!
% Yay, admin party!
@@ -118,11 +118,11 @@ proxy_authentification_handler(Req) ->
end.
proxy_auth_user(Req) ->
- XHeaderUserName = couch_config:get("couch_httpd_auth", "x_auth_username",
+ XHeaderUserName = config:get("couch_httpd_auth", "x_auth_username",
"X-Auth-CouchDB-UserName"),
- XHeaderRoles = couch_config:get("couch_httpd_auth", "x_auth_roles",
+ XHeaderRoles = config:get("couch_httpd_auth", "x_auth_roles",
"X-Auth-CouchDB-Roles"),
- XHeaderToken = couch_config:get("couch_httpd_auth", "x_auth_token",
+ XHeaderToken = config:get("couch_httpd_auth", "x_auth_token",
"X-Auth-CouchDB-Token"),
case header_value(Req, XHeaderUserName) of
undefined -> nil;
@@ -132,9 +132,9 @@ proxy_auth_user(Req) ->
Else ->
[?l2b(R) || R <- string:tokens(Else, ",")]
end,
- case couch_config:get("couch_httpd_auth", "proxy_use_secret", "false") of
+ case config:get("couch_httpd_auth", "proxy_use_secret", "false") of
"true" ->
- case couch_config:get("couch_httpd_auth", "secret", nil) of
+ case config:get("couch_httpd_auth", "secret", nil) of
nil ->
Req#httpd{user_ctx=#user_ctx{name=?l2b(UserName), roles=Roles}};
Secret ->
@@ -168,7 +168,7 @@ cookie_authentication_handler(#httpd{mochi_req=MochiReq}=Req) ->
end,
% Verify expiry and hash
CurrentTime = make_cookie_time(),
- case couch_config:get("couch_httpd_auth", "secret", nil) of
+ case config:get("couch_httpd_auth", "secret", nil) of
nil ->
?LOG_DEBUG("cookie auth secret is not set",[]),
Req;
@@ -182,7 +182,7 @@ cookie_authentication_handler(#httpd{mochi_req=MochiReq}=Req) ->
ExpectedHash = crypto:sha_mac(FullSecret, User ++ ":" ++ TimeStr),
Hash = ?l2b(HashStr),
Timeout = list_to_integer(
- couch_config:get("couch_httpd_auth", "timeout", "600")),
+ config:get("couch_httpd_auth", "timeout", "600")),
?LOG_DEBUG("timeout ~p", [Timeout]),
case (catch erlang:list_to_integer(TimeStr, 16)) of
TimeStamp when CurrentTime < TimeStamp + Timeout ->
@@ -232,10 +232,10 @@ cookie_auth_cookie(Req, User, Secret, TimeStamp) ->
[{path, "/"}] ++ cookie_scheme(Req) ++ max_age()).
ensure_cookie_auth_secret() ->
- case couch_config:get("couch_httpd_auth", "secret", nil) of
+ case config:get("couch_httpd_auth", "secret", nil) of
nil ->
NewSecret = ?b2l(couch_uuids:random()),
- couch_config:set("couch_httpd_auth", "secret", NewSecret),
+ config:set("couch_httpd_auth", "secret", NewSecret),
NewSecret;
Secret -> Secret
end.
@@ -311,9 +311,9 @@ handle_session_req(#httpd{method='GET', user_ctx=UserCtx}=Req) ->
{roles, UserCtx#user_ctx.roles}
]}},
{info, {[
- {authentication_db, ?l2b(couch_config:get("couch_httpd_auth", "authentication_db"))},
+ {authentication_db, ?l2b(config:get("couch_httpd_auth", "authentication_db"))},
{authentication_handlers, [auth_name(H) || H <- couch_httpd:make_fun_spec_strs(
- couch_config:get("httpd", "authentication_handlers"))]}
+ config:get("httpd", "authentication_handlers"))]}
] ++ maybe_value(authenticated, UserCtx#user_ctx.handler, fun(Handler) ->
auth_name(?b2l(Handler))
end)}}
@@ -366,11 +366,11 @@ cookie_scheme(#httpd{mochi_req=MochiReq}) ->
end.
max_age() ->
- case couch_config:get("couch_httpd_auth", "allow_persistent_cookies", "false") of
+ case config:get("couch_httpd_auth", "allow_persistent_cookies", "false") of
"false" ->
[];
"true" ->
Timeout = list_to_integer(
- couch_config:get("couch_httpd_auth", "timeout", "600")),
+ config:get("couch_httpd_auth", "timeout", "600")),
[{max_age, Timeout}]
end.
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/a7d16632/src/couch_httpd_cors.erl
----------------------------------------------------------------------
diff --git a/src/couch_httpd_cors.erl b/src/couch_httpd_cors.erl
index 5432fbd..d98357a 100644
--- a/src/couch_httpd_cors.erl
+++ b/src/couch_httpd_cors.erl
@@ -293,8 +293,8 @@ allow_credentials(_Origin, Host) ->
cors_config(Host, Key, Default) ->
- couch_config:get(cors_section(Host), Key,
- couch_config:get("cors", Key, Default)).
+ config:get(cors_section(Host), Key,
+ config:get("cors", Key, Default)).
cors_section(Host0) ->
{Host, _Port} = split_host_port(Host0),
@@ -304,7 +304,7 @@ enable_cors() ->
get_bool_config("httpd", "enable_cors", false).
get_bool_config(Section, Key, Default) ->
- case couch_config:get(Section, Key) of
+ case config:get(Section, Key) of
undefined ->
Default;
"true" ->
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/a7d16632/src/couch_httpd_db.erl
----------------------------------------------------------------------
diff --git a/src/couch_httpd_db.erl b/src/couch_httpd_db.erl
index 2ac4971..c70245c 100644
--- a/src/couch_httpd_db.erl
+++ b/src/couch_httpd_db.erl
@@ -63,7 +63,7 @@ handle_changes_req(#httpd{path_parts=[_,<<"_changes">>]}=Req, _Db) ->
send_method_not_allowed(Req, "GET,HEAD,POST").
handle_changes_req1(Req, #db{name=DbName}=Db) ->
- AuthDbName = ?l2b(couch_config:get("couch_httpd_auth", "authentication_db")),
+ AuthDbName = ?l2b(config:get("couch_httpd_auth", "authentication_db")),
case AuthDbName of
DbName ->
% in the authentication database, _changes is admin-only.
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/a7d16632/src/couch_httpd_external.erl
----------------------------------------------------------------------
diff --git a/src/couch_httpd_external.erl b/src/couch_httpd_external.erl
index 077136d..8322dcd 100644
--- a/src/couch_httpd_external.erl
+++ b/src/couch_httpd_external.erl
@@ -63,7 +63,7 @@ json_req_obj(#httpd{mochi_req=Req,
Body = case ReqBody of
undefined ->
MaxSize = list_to_integer(
- couch_config:get("couchdb", "max_document_size", "4294967296")),
+ config:get("couchdb", "max_document_size", "4294967296")),
Req:recv_body(MaxSize);
Else -> Else
end,
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/a7d16632/src/couch_httpd_misc_handlers.erl
----------------------------------------------------------------------
diff --git a/src/couch_httpd_misc_handlers.erl b/src/couch_httpd_misc_handlers.erl
index ff79f14..e46dee3 100644
--- a/src/couch_httpd_misc_handlers.erl
+++ b/src/couch_httpd_misc_handlers.erl
@@ -34,7 +34,7 @@ handle_welcome_req(#httpd{method='GET'}=Req, WelcomeMessage) ->
{couchdb, WelcomeMessage},
{uuid, couch_server:get_uuid()},
{version, list_to_binary(couch_server:get_version())}
- ] ++ case couch_config:get("vendor") of
+ ] ++ case config:get("vendor") of
[] ->
[];
Properties ->
@@ -137,7 +137,7 @@ handle_config_req(#httpd{method='GET', path_parts=[_]}=Req) ->
false ->
dict:store(Section, [{list_to_binary(Key), list_to_binary(Value)}], Acc)
end
- end, dict:new(), couch_config:all()),
+ end, dict:new(), config:all()),
KVs = dict:fold(fun(Section, Values, Acc) ->
[{list_to_binary(Section), {Values}} | Acc]
end, [], Grouped),
@@ -146,12 +146,12 @@ handle_config_req(#httpd{method='GET', path_parts=[_]}=Req) ->
handle_config_req(#httpd{method='GET', path_parts=[_,Section]}=Req) ->
ok = couch_httpd:verify_is_server_admin(Req),
KVs = [{list_to_binary(Key), list_to_binary(Value)}
- || {Key, Value} <- couch_config:get(Section)],
+ || {Key, Value} <- config:get(Section)],
send_json(Req, 200, {KVs});
% GET /_config/Section/Key
handle_config_req(#httpd{method='GET', path_parts=[_, Section, Key]}=Req) ->
ok = couch_httpd:verify_is_server_admin(Req),
- case couch_config:get(Section, Key, null) of
+ case config:get(Section, Key, null) of
null ->
throw({not_found, unknown_config_value});
Value ->
@@ -162,7 +162,7 @@ handle_config_req(#httpd{method=Method, path_parts=[_, Section, Key]}=Req)
when (Method == 'PUT') or (Method == 'DELETE') ->
ok = couch_httpd:verify_is_server_admin(Req),
Persist = couch_httpd:header_value(Req, "X-Couch-Persist") /= "false",
- case couch_config:get(<<"httpd">>, <<"config_whitelist">>, null) of
+ case config:get(<<"httpd">>, <<"config_whitelist">>, null) of
null ->
% No whitelist; allow all changes.
handle_approved_config_req(Req, Persist);
@@ -226,8 +226,8 @@ handle_approved_config_req(#httpd{method='PUT', path_parts=[_, Section, Key]}=Re
_ ->
couch_httpd:json_body(Req)
end,
- OldValue = couch_config:get(Section, Key, ""),
- case couch_config:set(Section, Key, ?b2l(Value), Persist) of
+ OldValue = config:get(Section, Key, ""),
+ case config:set(Section, Key, ?b2l(Value), Persist) of
ok ->
send_json(Req, 200, list_to_binary(OldValue));
Error ->
@@ -235,11 +235,11 @@ handle_approved_config_req(#httpd{method='PUT', path_parts=[_, Section, Key]}=Re
end;
% DELETE /_config/Section/Key
handle_approved_config_req(#httpd{method='DELETE',path_parts=[_,Section,Key]}=Req, Persist) ->
- case couch_config:get(Section, Key, null) of
+ case config:get(Section, Key, null) of
null ->
throw({not_found, unknown_config_value});
OldValue ->
- couch_config:delete(Section, Key, Persist),
+ config:delete(Section, Key, Persist),
send_json(Req, 200, list_to_binary(OldValue))
end.
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/a7d16632/src/couch_httpd_oauth.erl
----------------------------------------------------------------------
diff --git a/src/couch_httpd_oauth.erl b/src/couch_httpd_oauth.erl
index 57799e6..8fd4c30 100644
--- a/src/couch_httpd_oauth.erl
+++ b/src/couch_httpd_oauth.erl
@@ -309,17 +309,17 @@ oauth_credentials_info(Token, ConsumerKey) ->
Result;
nil ->
{
- case couch_config:get("oauth_consumer_secrets", ConsumerKey) of
+ case config:get("oauth_consumer_secrets", ConsumerKey) of
undefined -> [];
ConsumerSecret -> [{<<"consumer_secret">>, ?l2b(ConsumerSecret)}]
end
++
- case couch_config:get("oauth_token_secrets", Token) of
+ case config:get("oauth_token_secrets", Token) of
undefined -> [];
TokenSecret -> [{<<"token_secret">>, ?l2b(TokenSecret)}]
end
++
- case couch_config:get("oauth_token_users", Token) of
+ case config:get("oauth_token_users", Token) of
undefined -> [];
User -> [{<<"username">>, ?l2b(User)}]
end
@@ -328,7 +328,7 @@ oauth_credentials_info(Token, ConsumerKey) ->
use_auth_db() ->
- case couch_config:get("couch_httpd_oauth", "use_users_db", "false") of
+ case config:get("couch_httpd_oauth", "use_users_db", "false") of
"false" ->
nil;
"true" ->
@@ -338,7 +338,7 @@ use_auth_db() ->
open_auth_db() ->
- DbName = ?l2b(couch_config:get("couch_httpd_auth", "authentication_db")),
+ DbName = ?l2b(config:get("couch_httpd_auth", "authentication_db")),
DbOptions = [{user_ctx, #user_ctx{roles = [<<"_admin">>]}}],
{ok, AuthDb} = couch_db:open_int(DbName, DbOptions),
AuthDb.
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/a7d16632/src/couch_httpd_rewrite.erl
----------------------------------------------------------------------
diff --git a/src/couch_httpd_rewrite.erl b/src/couch_httpd_rewrite.erl
index 428d30c..abd6af5 100644
--- a/src/couch_httpd_rewrite.erl
+++ b/src/couch_httpd_rewrite.erl
@@ -119,7 +119,7 @@ handle_rewrite_req(#httpd{
Prefix = <<"/", (?l2b(couch_util:url_encode(DbName)))/binary, "/", DesignId/binary>>,
QueryList = lists:map(fun decode_query_value/1, couch_httpd:qs(Req)),
- MaxRewritesList = couch_config:get("httpd", "rewrite_limit", "100"),
+ MaxRewritesList = config:get("httpd", "rewrite_limit", "100"),
MaxRewrites = list_to_integer(MaxRewritesList),
case get(couch_rewrite_count) of
undefined ->
@@ -438,7 +438,7 @@ path_to_list([<<>>|R], Acc, DotDotCount) ->
path_to_list([<<"*">>|R], Acc, DotDotCount) ->
path_to_list(R, [?MATCH_ALL|Acc], DotDotCount);
path_to_list([<<"..">>|R], Acc, DotDotCount) when DotDotCount == 2 ->
- case couch_config:get("httpd", "secure_rewrites", "true") of
+ case config:get("httpd", "secure_rewrites", "true") of
"false" ->
path_to_list(R, [<<"..">>|Acc], DotDotCount+1);
_Else ->
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/a7d16632/src/couch_httpd_vhost.erl
----------------------------------------------------------------------
diff --git a/src/couch_httpd_vhost.erl b/src/couch_httpd_vhost.erl
index 258f4eb..29fddfe 100644
--- a/src/couch_httpd_vhost.erl
+++ b/src/couch_httpd_vhost.erl
@@ -12,13 +12,17 @@
-module(couch_httpd_vhost).
-behaviour(gen_server).
+-behaviour(config_listener).
--export([start_link/0, config_change/2, reload/0, get_state/0, dispatch_host/1]).
+-export([start_link/0, reload/0, get_state/0, dispatch_host/1]).
-export([urlsplit_netloc/2, redirect_to_vhost/2]).
-export([host/1, split_host_port/1]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
+% config_listener api
+-export([handle_config_change/5]).
+
-include_lib("couch/include/couch_db.hrl").
-define(SEPARATOR, $\/).
@@ -237,7 +241,7 @@ bind_path(_, _) ->
%% create vhost list from ini
host(MochiReq) ->
- XHost = couch_config:get("httpd", "x_forwarded_host",
+ XHost = config:get("httpd", "x_forwarded_host",
"X-Forwarded-Host"),
case MochiReq:get_header_value(XHost) of
undefined ->
@@ -254,7 +258,7 @@ make_vhosts() ->
Acc;
({Vhost, Path}, Acc) ->
[{parse_vhost(Vhost), split_path(Path)}|Acc]
- end, [], couch_config:get("vhosts")),
+ end, [], config:get("vhosts")),
lists:reverse(lists:usort(Vhosts)).
@@ -327,7 +331,7 @@ make_path(Parts) ->
"/" ++ string:join(Parts,[?SEPARATOR]).
init(_) ->
- ok = couch_config:register(fun ?MODULE:config_change/2),
+ ok = config:listen_for_changes(?MODULE, nil),
%% load configuration
{VHostGlobals, VHosts, Fun} = load_conf(),
@@ -351,6 +355,12 @@ handle_call(_Msg, _From, State) ->
handle_cast(_Msg, State) ->
{noreply, State}.
+handle_info({gen_event_EXIT, {config_listener, ?MODULE}, _Reason}, State) ->
+ erlang:send_after(5000, self(), restart_config_listener),
+ {noreply, State};
+handle_info(restart_config_listener, State) ->
+ ok = config:listen_for_changes(?MODULE, nil),
+ {noreply, State};
handle_info(_Info, State) ->
{noreply, State}.
@@ -360,16 +370,20 @@ terminate(_Reason, _State) ->
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
-config_change("httpd", "vhost_global_handlers") ->
- ?MODULE:reload();
-config_change("httpd", "redirect_vhost_handler") ->
- ?MODULE:reload();
-config_change("vhosts", _) ->
- ?MODULE:reload().
+
+handle_config_change("httpd", "vhost_global_handlers", _, _, _) ->
+ {ok, ?MODULE:reload()};
+handle_config_change("httpd", "redirect_vhost_handler", _, _, _) ->
+ {ok, ?MODULE:reload()};
+handle_config_change("vhosts", _, _, _, _) ->
+ {ok, ?MODULE:reload()};
+handle_config_change(_, _, _, _, _) ->
+ {ok, nil}.
+
load_conf() ->
%% get vhost globals
- VHostGlobals = re:split(couch_config:get("httpd",
+ VHostGlobals = re:split(config:get("httpd",
"vhost_global_handlers",""), "\\s*,\\s*",[{return, list}]),
%% build vhosts matching rules
@@ -377,7 +391,7 @@ load_conf() ->
%% build vhosts handler fun
DefaultVHostFun = "{couch_httpd_vhost, redirect_to_vhost}",
- Fun = couch_httpd:make_arity_2_fun(couch_config:get("httpd",
+ Fun = couch_httpd:make_arity_2_fun(config:get("httpd",
"redirect_vhost_handler", DefaultVHostFun)),
{VHostGlobals, VHosts, Fun}.
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/a7d16632/src/couch_log.erl
----------------------------------------------------------------------
diff --git a/src/couch_log.erl b/src/couch_log.erl
index cd4bbbb..d1aa701 100644
--- a/src/couch_log.erl
+++ b/src/couch_log.erl
@@ -12,6 +12,7 @@
-module(couch_log).
-behaviour(gen_event).
+-behaviour(config_listener).
% public API
-export([start_link/0, stop/0]).
@@ -24,6 +25,9 @@
-export([init/1, handle_event/2, terminate/2, code_change/3]).
-export([handle_info/2, handle_call/2]).
+% config_listener api
+-export([handle_config_change/5]).
+
-define(LEVEL_ERROR, 4).
-define(LEVEL_WARN, 3).
-define(LEVEL_INFO, 2).
@@ -71,25 +75,12 @@ stop() ->
couch_event_sup:stop(couch_log).
init([]) ->
- % read config and register for configuration changes
-
- % just stop if one of the config settings change. couch_server_sup
- % will restart us and then we will pick up the new settings.
- ok = couch_config:register(
- fun("log", "file") ->
- ?MODULE:stop();
- ("log", "level") ->
- ?MODULE:stop();
- ("log", "include_sasl") ->
- ?MODULE:stop();
- ("log_level_by_module", _) ->
- ?MODULE:stop()
- end),
-
- Filename = couch_config:get("log", "file", "couchdb.log"),
- Level = level_integer(list_to_atom(couch_config:get("log", "level", "info"))),
- Sasl = couch_config:get("log", "include_sasl", "true") =:= "true",
- LevelByModule = couch_config:get("log_level_by_module"),
+ ok = config:listen_for_changes(?MODULE, nil),
+
+ Filename = config:get("log", "file", "couchdb.log"),
+ Level = level_integer(list_to_atom(config:get("log", "level", "info"))),
+ Sasl = config:get("log", "include_sasl", "true") =:= "true",
+ LevelByModule = config:get("log_level_by_module"),
case ets:info(?MODULE) of
undefined -> ets:new(?MODULE, [named_table]);
@@ -111,6 +102,18 @@ init([]) ->
{stop, {error, ReasonStr, Filename}}
end.
+handle_config_change("log", "file", _, _, _) ->
+ ?MODULE:stop(),
+ remove_handler;
+handle_config_change("log", "level", _, _, _) ->
+ ?MODULE:stop(),
+ remove_handler;
+handle_config_change("log", "include_sasl", _, _, _) ->
+ ?MODULE:stop(),
+ remove_handler;
+handle_config_change(_, _, _, _, _) ->
+ {ok, nil}.
+
debug_on() ->
get_level_integer() =< ?LEVEL_DEBUG.
@@ -194,6 +197,12 @@ handle_call({set_level_integer, Module, NewLevel}, State) ->
ets:insert(?MODULE, {Module, NewLevel}),
{ok, ok, State#state{level = NewLevel}}.
+handle_info({gen_event_EXIT, {config_listener, ?MODULE}, _Reason}, State) ->
+ erlang:send_after(5000, self(), restart_config_listener),
+ {ok, State};
+handle_info(restart_config_listener, State) ->
+ ok = config:listen_for_changes(?MODULE, nil),
+ {ok, State};
handle_info(_Info, State) ->
{ok, State}.
@@ -231,10 +240,10 @@ get_log_messages(Pid, Level, Format, Args) ->
% |__________| 100
read(Bytes, Offset) ->
- LogFileName = couch_config:get("log", "file"),
+ LogFileName = config:get("log", "file"),
LogFileSize = filelib:file_size(LogFileName),
MaxChunkSize = list_to_integer(
- couch_config:get("httpd", "log_max_chunk_size", "1000000")),
+ config:get("httpd", "log_max_chunk_size", "1000000")),
case Bytes > MaxChunkSize of
true ->
throw({bad_request, "'bytes' cannot exceed " ++
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/a7d16632/src/couch_os_daemons.erl
----------------------------------------------------------------------
diff --git a/src/couch_os_daemons.erl b/src/couch_os_daemons.erl
index 00fd7b3..3560149 100644
--- a/src/couch_os_daemons.erl
+++ b/src/couch_os_daemons.erl
@@ -11,12 +11,16 @@
% the License.
-module(couch_os_daemons).
-behaviour(gen_server).
+-behaviour(config_listener).
--export([start_link/0, info/0, info/1, config_change/2]).
+-export([start_link/0, info/0, info/1]).
-export([init/1, terminate/2, code_change/3]).
-export([handle_call/3, handle_cast/2, handle_info/2]).
+% config_listener api
+-export([handle_config_change/5]).
+
-include_lib("couch/include/couch_db.hrl").
-record(daemon, {
@@ -42,12 +46,9 @@ info() ->
info(Options) ->
gen_server:call(?MODULE, {daemon_info, Options}).
-config_change(Section, Key) ->
- gen_server:cast(?MODULE, {config_change, Section, Key}).
-
init(_) ->
process_flag(trap_exit, true),
- ok = couch_config:register(fun ?MODULE:config_change/2),
+ ok = config:listen_for_changes(?MODULE, nil),
Table = ets:new(?MODULE, [protected, set, {keypos, #daemon.port}]),
reload_daemons(Table),
{ok, Table}.
@@ -80,6 +81,12 @@ handle_cast(Msg, Table) ->
?LOG_ERROR("Unknown cast message to ~p: ~p", [?MODULE, Msg]),
{stop, error, Table}.
+handle_info({gen_event_EXIT, {config_listener, ?MODULE}, _Reason}, State) ->
+ erlang:send_after(5000, self(), restart_config_listener),
+ {noreply, State};
+handle_info(restart_config_listener, State) ->
+ ok = config:listen_for_changes(?MODULE, nil),
+ {noreply, State};
handle_info({'EXIT', Port, Reason}, Table) ->
case ets:lookup(Table, Port) of
[] ->
@@ -186,6 +193,12 @@ handle_info(Msg, Table) ->
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
+
+handle_config_change(Section, Key, _, _, _) ->
+ gen_server:cast(?MODULE, {config_change, Section, Key}),
+ {ok, nil}.
+
+
% Internal API
%
@@ -209,13 +222,13 @@ stop_port(#daemon{port=Port}=D) ->
handle_port_message(#daemon{port=Port}=Daemon, [<<"get">>, Section]) ->
- KVs = couch_config:get(Section),
+ KVs = config:get(Section),
Data = lists:map(fun({K, V}) -> {?l2b(K), ?l2b(V)} end, KVs),
Json = iolist_to_binary(?JSON_ENCODE({Data})),
port_command(Port, <<Json/binary, "\n">>),
{ok, Daemon};
handle_port_message(#daemon{port=Port}=Daemon, [<<"get">>, Section, Key]) ->
- Value = case couch_config:get(Section, Key, null) of
+ Value = case config:get(Section, Key, null) of
null -> null;
String -> ?l2b(String)
end,
@@ -260,7 +273,7 @@ handle_log_message(Name, Msg, Level) ->
reload_daemons(Table) ->
% List of daemons we want to have running.
- Configured = lists:sort(couch_config:get("os_daemons")),
+ Configured = lists:sort(config:get("os_daemons")),
% Remove records for daemons that were halted.
MSpecHalted = #daemon{name='$1', cmd='$2', status=halted, _='_'},
@@ -350,7 +363,7 @@ find_to_stop(_, [], Acc) ->
Acc.
should_halt(Errors) ->
- RetryTimeCfg = couch_config:get("os_daemon_settings", "retry_time", "5"),
+ RetryTimeCfg = config:get("os_daemon_settings", "retry_time", "5"),
RetryTime = list_to_integer(RetryTimeCfg),
Now = now(),
@@ -358,7 +371,7 @@ should_halt(Errors) ->
timer:now_diff(Now, Time) =< RetryTime * 1000000
end, Errors),
- RetryCfg = couch_config:get("os_daemon_settings", "max_retries", "3"),
+ RetryCfg = config:get("os_daemon_settings", "max_retries", "3"),
Retries = list_to_integer(RetryCfg),
{length(RecentErrors) >= Retries, RecentErrors}.
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/a7d16632/src/couch_os_process.erl
----------------------------------------------------------------------
diff --git a/src/couch_os_process.erl b/src/couch_os_process.erl
index fcf9da5..c6e6520 100644
--- a/src/couch_os_process.erl
+++ b/src/couch_os_process.erl
@@ -178,7 +178,7 @@ pick_command1(_) ->
init([Command, Options, PortOptions]) ->
PrivDir = couch_util:priv_dir(),
Spawnkiller = filename:join(PrivDir, "couchspawnkillable"),
- V = couch_config:get("query_server_config", "os_process_idle_limit", "300"),
+ V = config:get("query_server_config", "os_process_idle_limit", "300"),
IdleLimit = list_to_integer(V) * 1000,
BaseProc = #os_proc{
command=Command,
@@ -263,7 +263,7 @@ handle_info(Msg, #os_proc{idle=Idle}=OsProc) ->
{noreply, OsProc, Idle}.
code_change(_, {os_proc, Cmd, Port, W, R, Timeout} , _) ->
- V = couch_config:get("query_server_config","os_process_idle_limit","300"),
+ V = config:get("query_server_config","os_process_idle_limit","300"),
State = #os_proc{
command = Cmd,
port = Port,
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/a7d16632/src/couch_passwords.erl
----------------------------------------------------------------------
diff --git a/src/couch_passwords.erl b/src/couch_passwords.erl
index 43f3380..d0f36cc 100644
--- a/src/couch_passwords.erl
+++ b/src/couch_passwords.erl
@@ -28,7 +28,7 @@ simple(Password, Salt) ->
%% CouchDB utility functions
-spec hash_admin_password(binary()) -> binary().
hash_admin_password(ClearPassword) ->
- Iterations = couch_config:get("couch_httpd_auth", "iterations", "10000"),
+ Iterations = config:get("couch_httpd_auth", "iterations", "10000"),
Salt = couch_uuids:random(),
DerivedKey = couch_passwords:pbkdf2(couch_util:to_binary(ClearPassword),
Salt ,list_to_integer(Iterations)),
@@ -46,7 +46,7 @@ get_unhashed_admins() ->
({_User, _ClearPassword}) ->
true
end,
- couch_config:get("admins")).
+ config:get("admins")).
%% Current scheme, much stronger.
-spec pbkdf2(binary(), binary(), integer()) -> binary().
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/a7d16632/src/couch_proc_manager.erl
----------------------------------------------------------------------
diff --git a/src/couch_proc_manager.erl b/src/couch_proc_manager.erl
index 94946a1..6130fc9 100644
--- a/src/couch_proc_manager.erl
+++ b/src/couch_proc_manager.erl
@@ -100,7 +100,7 @@ handle_call(_Call, _From, State) ->
{reply, ignored, State}.
handle_cast({os_proc_idle, Pid}, #state{tab=Tab}=State) ->
- Limit = couch_config:get("query_server_config", "os_process_soft_limit", "100"),
+ Limit = config:get("query_server_config", "os_process_soft_limit", "100"),
case ets:lookup(Tab, Pid) of
[#proc{client=nil}] ->
case ets:info(Tab, size) > list_to_integer(Limit) of
@@ -225,9 +225,9 @@ new_proc(From, Lang, DDoc, DDocKey) ->
new_proc_int(From, Lang) when is_binary(Lang) ->
new_proc_int(From, binary_to_list(Lang));
new_proc_int(From, Lang) when is_list(Lang) ->
- case couch_config:get("query_servers", Lang) of
+ case config:get("query_servers", Lang) of
undefined ->
- case couch_config:get("native_query_servers", Lang) of
+ case config:get("native_query_servers", Lang) of
undefined ->
gen_server:reply(From, {unknown_query_language, Lang});
SpecStr ->
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/a7d16632/src/couch_secondary_sup.erl
----------------------------------------------------------------------
diff --git a/src/couch_secondary_sup.erl b/src/couch_secondary_sup.erl
index 6320fd9..4f2d1c8 100644
--- a/src/couch_secondary_sup.erl
+++ b/src/couch_secondary_sup.erl
@@ -38,5 +38,5 @@ init([]) ->
[Module]}
end
|| {Name, SpecStr}
- <- couch_config:get("daemons"), SpecStr /= ""],
+ <- config:get("daemons"), SpecStr /= ""],
{ok, {{one_for_one, 10, 3600}, Children}}.
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/a7d16632/src/couch_server.erl
----------------------------------------------------------------------
diff --git a/src/couch_server.erl b/src/couch_server.erl
index 40c2d7e..c23ec05 100644
--- a/src/couch_server.erl
+++ b/src/couch_server.erl
@@ -12,14 +12,18 @@
-module(couch_server).
-behaviour(gen_server).
+-behaviour(config_listener).
-export([open/2,create/2,delete/2,get_version/0,get_uuid/0]).
-export([all_databases/0, all_databases/2]).
-export([init/1, handle_call/3,sup_start_link/0]).
-export([handle_cast/2,code_change/3,handle_info/2,terminate/2]).
--export([dev_start/0,is_admin/2,has_admins/0,get_stats/0,config_change/4]).
+-export([dev_start/0,is_admin/2,has_admins/0,get_stats/0]).
-export([close_lru/0]).
+% config_listener api
+-export([handle_config_change/5]).
+
-include_lib("couch/include/couch_db.hrl").
-record(server,{
@@ -46,10 +50,10 @@ get_version() ->
end.
get_uuid() ->
- case couch_config:get("couchdb", "uuid", nil) of
+ case config:get("couchdb", "uuid", nil) of
nil ->
UUID = couch_uuids:random(),
- couch_config:set("couchdb", "uuid", ?b2l(UUID)),
+ config:set("couchdb", "uuid", ?b2l(UUID)),
UUID;
UUID -> ?l2b(UUID)
end.
@@ -105,7 +109,7 @@ delete(DbName, Options) ->
maybe_add_sys_db_callbacks(DbName, Options) when is_binary(DbName) ->
maybe_add_sys_db_callbacks(?b2l(DbName), Options);
maybe_add_sys_db_callbacks(DbName, Options) ->
- case couch_config:get("replicator", "db", "_replicator") of
+ case config:get("replicator", "db", "_replicator") of
DbName ->
[
{before_doc_update, fun couch_replicator_manager:before_doc_update/2},
@@ -113,7 +117,7 @@ maybe_add_sys_db_callbacks(DbName, Options) ->
sys_db | Options
];
_ ->
- case couch_config:get("couch_httpd_auth", "authentication_db", "_users") of
+ case config:get("couch_httpd_auth", "authentication_db", "_users") of
DbName ->
[
{before_doc_update, fun couch_users_db:before_doc_update/2},
@@ -139,7 +143,7 @@ check_dbname(#server{dbname_regexp=RegExp}, DbName) ->
end.
is_admin(User, ClearPwd) ->
- case couch_config:get("admins", User) of
+ case config:get("admins", User) of
"-hashed-" ++ HashedPwdAndSalt ->
[HashedPwd, Salt] = string:tokens(HashedPwdAndSalt, ","),
couch_util:to_hex(crypto:sha(ClearPwd ++ Salt)) == HashedPwd;
@@ -148,7 +152,7 @@ is_admin(User, ClearPwd) ->
end.
has_admins() ->
- couch_config:get("admins") /= [].
+ config:get("admins") /= [].
get_full_filename(Server, DbName) ->
filename:join([Server#server.root_dir, "./" ++ DbName ++ ".couch"]).
@@ -160,7 +164,7 @@ hash_admin_passwords(Persist) ->
lists:foreach(
fun({User, ClearPassword}) ->
HashedPassword = couch_passwords:hash_admin_password(ClearPassword),
- couch_config:set("admins", User, ?b2l(HashedPassword), Persist)
+ config:set("admins", User, ?b2l(HashedPassword), Persist)
end, couch_passwords:get_unhashed_admins()).
init([]) ->
@@ -169,10 +173,10 @@ init([]) ->
% just stop if one of the config settings change. couch_server_sup
% will restart us and then we will pick up the new settings.
- RootDir = couch_config:get("couchdb", "database_dir", "."),
+ RootDir = config:get("couchdb", "database_dir", "."),
MaxDbsOpen = list_to_integer(
- couch_config:get("couchdb", "max_dbs_open")),
- ok = couch_config:register(fun ?MODULE:config_change/4),
+ config:get("couchdb", "max_dbs_open")),
+ ok = config:listen_for_changes(?MODULE, nil),
ok = couch_file:init_delete_dir(RootDir),
hash_admin_passwords(),
{ok, RegExp} = re:compile(
@@ -191,13 +195,31 @@ terminate(_Reason, _Srv) ->
nil, couch_dbs),
ok.
-config_change("couchdb", "database_dir", _, _) ->
- exit(whereis(couch_server), config_change);
-config_change("couchdb", "max_dbs_open", Max, _) ->
- gen_server:call(couch_server, {set_max_dbs_open, list_to_integer(Max)});
-config_change("admins", _, _, Persist) ->
+handle_config_change("couchdb", "database_dir", _, _, _) ->
+ exit(whereis(couch_server), config_change),
+ remove_handler;
+handle_config_change("couchdb", "max_dbs_open", Max, _, _) ->
+ {ok, gen_server:call(couch_server,{set_max_dbs_open,list_to_integer(Max)})};
+handle_config_change("admins", _, _, Persist, _) ->
% spawn here so couch event manager doesn't deadlock
- spawn(fun() -> hash_admin_passwords(Persist) end).
+ {ok, spawn(fun() -> hash_admin_passwords(Persist) end)};
+handle_config_change("httpd", "authentication_handlers", _, _, _) ->
+ {ok, couch_httpd:stop()};
+handle_config_change("httpd", "bind_address", _, _, _) ->
+ {ok, couch_httpd:stop()};
+handle_config_change("httpd", "port", _, _, _) ->
+ {ok, couch_httpd:stop()};
+handle_config_change("httpd", "max_connections", _, _, _) ->
+ {ok, couch_httpd:stop()};
+handle_config_change("httpd", "default_handler", _, _, _) ->
+ {ok, couch_httpd:stop()};
+handle_config_change("httpd_global_handlers", _, _, _, _) ->
+ {ok, couch_httpd:stop()};
+handle_config_change("httpd_db_handlers", _, _, _, _) ->
+ {ok, couch_httpd:stop()};
+handle_config_change(_, _, _, _, _) ->
+ {ok, nil}.
+
all_databases() ->
{ok, DbList} = all_databases(
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/a7d16632/src/couch_server_sup.erl
----------------------------------------------------------------------
diff --git a/src/couch_server_sup.erl b/src/couch_server_sup.erl
index 528ac7c..c42bcfb 100644
--- a/src/couch_server_sup.erl
+++ b/src/couch_server_sup.erl
@@ -12,16 +12,19 @@
-module(couch_server_sup).
-behaviour(supervisor).
+-behaviour(config_listener).
--export([start_link/1,stop/0, couch_config_start_link_wrapper/2,
- restart_core_server/0, config_change/2]).
+-export([start_link/1,stop/0, restart_core_server/0]).
-include_lib("couch/include/couch_db.hrl").
%% supervisor callbacks
-export([init/1]).
+% config_listener api
+-export([handle_config_change/5]).
+
start_link(IniFiles) ->
case whereis(couch_server_sup) of
undefined ->
@@ -33,14 +36,6 @@ start_link(IniFiles) ->
restart_core_server() ->
init:restart().
-couch_config_start_link_wrapper(IniFiles, FirstConfigPid) ->
- case is_process_alive(FirstConfigPid) of
- true ->
- link(FirstConfigPid),
- {ok, FirstConfigPid};
- false -> couch_config:start_link(IniFiles)
- end.
-
start_server(IniFiles) ->
case init:get_argument(pidfile) of
{ok, [PidFile]} ->
@@ -53,9 +48,7 @@ start_server(IniFiles) ->
_ -> ok
end,
- {ok, ConfigPid} = couch_config:start_link(IniFiles),
-
- LogLevel = couch_config:get("log", "level", "info"),
+ LogLevel = config:get("log", "level", "info"),
% announce startup
io:format("Apache CouchDB ~s (LogLevel=~s) is starting.~n", [
couch_server:get_version(),
@@ -65,18 +58,12 @@ start_server(IniFiles) ->
"debug" ->
io:format("Configuration Settings ~p:~n", [IniFiles]),
[io:format(" [~s] ~s=~p~n", [Module, Variable, Value])
- || {{Module, Variable}, Value} <- couch_config:all()];
+ || {{Module, Variable}, Value} <- config:all()];
_ -> ok
end,
BaseChildSpecs =
- {{one_for_one, 10, 60},
- [{couch_config,
- {couch_server_sup, couch_config_start_link_wrapper, [IniFiles, ConfigPid]},
- permanent,
- brutal_kill,
- worker,
- [couch_config]},
+ {{one_for_one, 10, 60}, [
{couch_primary_services,
{couch_primary_sup, start_link, []},
permanent,
@@ -98,13 +85,9 @@ start_server(IniFiles) ->
{ok, Pid} = supervisor:start_link(
{local, couch_server_sup}, couch_server_sup, BaseChildSpecs),
- % launch the icu bridge
- % just restart if one of the config settings change.
- couch_config:register(fun ?MODULE:config_change/2, Pid),
-
- unlink(ConfigPid),
+ ok = config:listen_for_changes(?MODULE, nil),
- Ip = couch_config:get("httpd", "bind_address"),
+ Ip = config:get("httpd", "bind_address"),
io:format("Apache CouchDB has started. Time to relax.~n"),
Uris = [get_uri(Name, Ip) || Name <- [couch_httpd, https]],
[begin
@@ -114,7 +97,7 @@ start_server(IniFiles) ->
end
end
|| Uri <- Uris],
- case couch_config:get("couchdb", "uri_file", null) of
+ case config:get("couchdb", "uri_file", null) of
null -> ok;
UriFile ->
Lines = [begin case Uri of
@@ -135,13 +118,17 @@ start_server(IniFiles) ->
stop() ->
catch exit(whereis(couch_server_sup), normal).
-config_change("daemons", _) ->
- supervisor:terminate_child(couch_server_sup, couch_secondary_services),
- supervisor:restart_child(couch_server_sup, couch_secondary_services);
-config_change("couchdb", "util_driver_dir") ->
+
+handle_config_change("daemons", _, _, _, _) ->
+ exit(whereis(couch_server_sup), shutdown),
+ remove_handler;
+handle_config_change("couchdb", "util_driver_dir", _, _, _) ->
[Pid] = [P || {collation_driver, P, _, _}
<- supervisor:which_children(couch_primary_services)],
- Pid ! reload_driver.
+ Pid ! reload_driver,
+ {ok, nil};
+handle_config_change(_, _, _, _, _) ->
+ {ok, nil}.
init(ChildSpecs) ->
{ok, ChildSpecs}.
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/a7d16632/src/couch_stats_aggregator.erl
----------------------------------------------------------------------
diff --git a/src/couch_stats_aggregator.erl b/src/couch_stats_aggregator.erl
index 6090355..416c9a0 100644
--- a/src/couch_stats_aggregator.erl
+++ b/src/couch_stats_aggregator.erl
@@ -12,6 +12,7 @@
-module(couch_stats_aggregator).
-behaviour(gen_server).
+-behaviour(config_listener).
-export([start/0, start/1, stop/0]).
-export([all/0, all/1, get/1, get/2, get_json/1, get_json/2, collect_sample/0]).
@@ -19,6 +20,10 @@
-export([init/1, terminate/2, code_change/3]).
-export([handle_call/3, handle_cast/2, handle_info/2]).
+% config_listener api
+-export([handle_config_change/5]).
+
+
-record(aggregate, {
description = <<"">>,
seconds = 0,
@@ -92,7 +97,7 @@ collect_sample() ->
init(StatDescsFileName) ->
% Create an aggregate entry for each {description, rate} pair.
ets:new(?MODULE, [named_table, set, protected]),
- SampleStr = couch_config:get("stats", "samples", "[0]"),
+ SampleStr = config:get("stats", "samples", "[0]"),
{ok, Samples} = couch_util:parse_term(SampleStr),
{ok, Descs} = file:consult(StatDescsFileName),
lists:foreach(fun({Sect, Key, Value}) ->
@@ -105,12 +110,9 @@ init(StatDescsFileName) ->
end, Samples)
end, Descs),
- Self = self(),
- ok = couch_config:register(
- fun("stats", _) -> exit(Self, config_change) end
- ),
+ ok = config:listen_for_changes(?MODULE, nil),
- Rate = list_to_integer(couch_config:get("stats", "rate", "1000")),
+ Rate = list_to_integer(config:get("stats", "rate", "1000")),
% TODO: Add timer_start to kernel start options.
{ok, TRef} = timer:apply_after(Rate, ?MODULE, collect_sample, []),
{ok, {TRef, Rate}}.
@@ -156,6 +158,12 @@ handle_call(collect_sample, _, {OldTRef, SampleInterval}) ->
handle_cast(stop, State) ->
{stop, normal, State}.
+handle_info({gen_event_EXIT, {config_listener, ?MODULE}, _Reason}, State) ->
+ erlang:send_after(5000, self(), restart_config_listener),
+ {noreply, State};
+handle_info(restart_config_listener, State) ->
+ ok = config:listen_for_changes(?MODULE, nil),
+ {noreply, State};
handle_info(_Info, State) ->
{noreply, State}.
@@ -163,6 +171,13 @@ code_change(_OldVersion, State, _Extra) ->
{ok, State}.
+handle_config_change("stats", _, _, _, _) ->
+ exit(whereis(?MODULE), config_change),
+ remove_handler;
+handle_config_change(_, _, _, _, _) ->
+ {ok, nil}.
+
+
new_value(incremental, Value, null) ->
Value;
new_value(incremental, Value, Current) ->
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/a7d16632/src/couch_users_db.erl
----------------------------------------------------------------------
diff --git a/src/couch_users_db.erl b/src/couch_users_db.erl
index 9fe069f..76acfee 100644
--- a/src/couch_users_db.erl
+++ b/src/couch_users_db.erl
@@ -63,7 +63,7 @@ save_doc(#doc{body={Body}} = Doc) ->
undefined ->
Doc;
ClearPassword ->
- Iterations = list_to_integer(couch_config:get("couch_httpd_auth", "iterations", "1000")),
+ Iterations = list_to_integer(config:get("couch_httpd_auth", "iterations", "1000")),
Salt = couch_uuids:random(),
DerivedKey = couch_passwords:pbkdf2(ClearPassword, Salt, Iterations),
Body0 = [{?PASSWORD_SCHEME, ?PBKDF2}, {?ITERATIONS, Iterations}|Body],
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/a7d16632/src/couch_uuids.erl
----------------------------------------------------------------------
diff --git a/src/couch_uuids.erl b/src/couch_uuids.erl
index ac9b463..3065938 100644
--- a/src/couch_uuids.erl
+++ b/src/couch_uuids.erl
@@ -13,6 +13,7 @@
-include_lib("couch/include/couch_db.hrl").
-behaviour(gen_server).
+-behaviour(config_listener).
-export([start/0, stop/0]).
-export([new/0, random/0, utc_random/0]).
@@ -20,6 +21,9 @@
-export([init/1, terminate/2, code_change/3]).
-export([handle_call/3, handle_cast/2, handle_info/2]).
+% config_listener api
+-export([handle_config_change/5]).
+
start() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
@@ -44,9 +48,7 @@ utc_suffix(Suffix) ->
list_to_binary(Prefix ++ Suffix).
init([]) ->
- ok = couch_config:register(
- fun("uuids", _) -> gen_server:cast(?MODULE, change) end
- ),
+ ok = config:listen_for_changes(?MODULE, nil),
{ok, state()}.
terminate(_Reason, _State) ->
@@ -74,12 +76,23 @@ handle_cast(stop, State) ->
handle_cast(_Msg, State) ->
{noreply, State}.
+handle_info({gen_event_EXIT, {config_listener, ?MODULE}, _Reason}, State) ->
+ erlang:send_after(5000, self(), restart_config_listener),
+ {noreply, State};
+handle_info(restart_config_listener, State) ->
+ ok = config:listen_for_changes(?MODULE, nil),
+ {noreply, State};
handle_info(_Info, State) ->
{noreply, State}.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
+handle_config_change("uuids", _, _, _, _) ->
+ {ok, gen_server:cast(?MODULE, change)};
+handle_config_change(_, _, _, _, _) ->
+ {ok, nil}.
+
new_prefix() ->
couch_util:to_hex((crypto:rand_bytes(13))).
@@ -87,14 +100,14 @@ inc() ->
crypto:rand_uniform(1, 16#ffe).
state() ->
- AlgoStr = couch_config:get("uuids", "algorithm", "random"),
+ AlgoStr = config:get("uuids", "algorithm", "random"),
case couch_util:to_existing_atom(AlgoStr) of
random ->
random;
utc_random ->
utc_random;
utc_id ->
- UtcIdSuffix = couch_config:get("uuids", "utc_id_suffix", ""),
+ UtcIdSuffix = config:get("uuids", "utc_id_suffix", ""),
{utc_id, UtcIdSuffix};
sequential ->
{sequential, new_prefix(), inc()};