nickva commented on a change in pull request #756: Make couch_peruser a proper 
Erlang app
URL: https://github.com/apache/couchdb/pull/756#discussion_r143627829
 
 

 ##########
 File path: src/couch_peruser/src/couch_peruser.erl
 ##########
 @@ -12,62 +12,113 @@
 
 -module(couch_peruser).
 -behaviour(gen_server).
+-behaviour(mem3_cluster).
 
 -include_lib("couch/include/couch_db.hrl").
 -include_lib("mem3/include/mem3.hrl").
 
--define(USERDB_PREFIX, "userdb-").
-
 % gen_server callbacks
 -export([start_link/0, init/1, handle_call/3, handle_cast/2, handle_info/2,
          terminate/2, code_change/3]).
 
 -export([init_changes_handler/1, changes_handler/3]).
 
--record(state, {parent, db_name, delete_dbs, changes_pid, changes_ref}).
--record(clusterState, {parent, db_name, delete_dbs, states}).
+% mem3_cluster callbacks
+-export([
+    cluster_stable/1,
+    cluster_unstable/1
+]).
+
+-record(changes_state, {
+    parent :: pid(),
+    db_name :: binary(),
+    delete_dbs :: boolean(),
+    changes_pid :: pid(),
+    changes_ref :: reference()
+}).
+
+-record(state, {
+    parent :: pid(),
+    db_name :: binary(),
+    delete_dbs :: boolean(),
+    states :: list(),
+    mem3_cluster_pid :: pid(),
+    cluster_stable :: boolean()
+}).
 
+-define(USERDB_PREFIX, "userdb-").
 -define(RELISTEN_DELAY, 5000).
+-define(DEFAULT_QUIET_PERIOD, 60). % seconds
+-define(DEFAULT_START_PERIOD, 5). % seconds
 
-
+%%
+%% Please leave in the commented-out couch_log:debug calls, thanks! ? Jan
+%%
+-spec start_link() -> {ok, pid()} | ignore | {error, term()}.
 start_link() ->
-    gen_server:start_link(?MODULE, [], []).
+    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
 
-init() ->
+-spec init_state() -> #state{}.
+init_state() ->
+    couch_log:debug("peruser: starting on node ~p in pid ~p", [node(), 
self()]),
     case config:get_boolean("couch_peruser", "enable", false) of
     false ->
-        #clusterState{};
+        couch_log:debug("peruser: disabled on node ~p", [node()]),
+        #state{};
     true ->
+        couch_log:debug("peruser: enabled on node ~p", [node()]),
         DbName = ?l2b(config:get(
                          "couch_httpd_auth", "authentication_db", "_users")),
         DeleteDbs = config:get_boolean("couch_peruser", "delete_dbs", false),
 
-        ClusterState = #clusterState{
+        % set up cluster-stable listener
+        Period = abs(config:get_integer("couch_peruser", 
"cluster_quiet_period",
+            ?DEFAULT_QUIET_PERIOD)),
+        StartPeriod = abs(config:get_integer("couch_peruser", 
"cluster_start_period",
+            ?DEFAULT_START_PERIOD)),
+
+        {ok, Mem3Cluster} = mem3_cluster:start_link(?MODULE, self(), 
StartPeriod,
+            Period),
+
+        #state{
             parent = self(),
             db_name = DbName,
-            delete_dbs = DeleteDbs
-        },
-        try
-            States = lists:map(fun (A) ->
-                S = #state{parent = ClusterState#clusterState.parent,
-                           db_name = A#shard.name,
-                           delete_dbs = DeleteDbs},
-                {Pid, Ref} = spawn_opt(
-                    ?MODULE, init_changes_handler, [S], [link, monitor]),
-                S#state{changes_pid=Pid, changes_ref=Ref}
-            end, mem3:local_shards(DbName)),
-
-            ClusterState#clusterState{states = States}
-        catch error:database_does_not_exist ->
-            couch_log:warning("couch_peruser can't proceed as underlying 
database (~s) is missing, disables itself.", [DbName]),
-            config:set("couch_peruser", "enable", "false", 
lists:concat([binary_to_list(DbName), " is missing"]))
-        end
+            delete_dbs = DeleteDbs,
+            mem3_cluster_pid = Mem3Cluster,
+            cluster_stable = false
+        }
     end.
 
-init_changes_handler(#state{db_name=DbName} = State) ->
+
+-spec start_listening(State :: #state{}) -> #state{} | ok.
+start_listening(#state{states=ChangesStates}=State) when length(ChangesStates) 
> 0 ->
+    % couch_log:debug("peruser: start_listening() already run on node ~p in 
pid ~p", [node(), self()]),
+    State;
+start_listening(#state{db_name=DbName, delete_dbs=DeleteDbs} = State) ->
+    % couch_log:debug("peruser: start_listening() on node ~p", [node()]),
+    try
+        States = lists:map(fun (A) ->
+            S = #changes_state{parent = State#state.parent,
 
 Review comment:
   This was like this before, but wonder since it was copies and moved if it is 
better to format it nicer, something like
   
   ```
   S = #changes_state{
       parent = State#state.parent,
       db_name = A#shard.name,
       delete_dbs = DeleteDbs
   },
   ...
   ```
 
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

Reply via email to