Skip to content
This repository has been archived by the owner on Sep 4, 2019. It is now read-only.

Commit

Permalink
Avoid a race condition for monitored compaction.
Browse files Browse the repository at this point in the history
It was technically possible for compaction to finish before a monitor
was requested. This fixes that by giving couch_index:compact a third
options parameter that accepts the atom 'monitor' which will then return
{ok, MonRef} instead of a bare ok.



git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@1172378 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
davisp committed Sep 18, 2011
1 parent 67a9951 commit 3f2e857
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 27 deletions.
16 changes: 10 additions & 6 deletions src/couch_index/src/couch_index.erl
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

%% API
-export([start_link/1, stop/1, get_state/2, get_info/1]).
-export([compact/1, get_compactor_pid/1]).
-export([compact/1, compact/2]).
-export([config_change/3]).

%% gen_server callbacks
Expand Down Expand Up @@ -55,11 +55,15 @@ get_info(Pid) ->


compact(Pid) ->
gen_server:call(Pid, compact).
compact(Pid, []).


get_compactor_pid(Pid) ->
gen_server:call(Pid, get_compactor_pid).
compact(Pid, Options) ->
{ok, CPid} = gen_server:call(Pid, compact),
case lists:member(monitor, Options) of
true -> {ok, erlang:monitor(process, CPid)};
false -> ok
end.


config_change("query_server_config", "commit_freq", NewValue) ->
Expand Down Expand Up @@ -155,8 +159,8 @@ handle_call(reset, _From, State) ->
{ok, NewIdxState} = Mod:reset(IdxState),
{reply, {ok, NewIdxState}, State#st{idx_state=NewIdxState}};
handle_call(compact, _From, State) ->
couch_index_compactor:run(State#st.compactor, State#st.idx_state),
{reply, ok, State};
Resp = couch_index_compactor:run(State#st.compactor, State#st.idx_state),
{reply, Resp, State};
handle_call(get_compactor_pid, _From, State) ->
{reply, {ok, State#st.compactor}, State};
handle_call({compacted, NewIdxState}, _From, State) ->
Expand Down
15 changes: 3 additions & 12 deletions src/couch_index/src/couch_index_compactor.erl
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@


%% API
-export([start_link/2, run/2, monitor/1, cancel/1, is_running/1]).
-export([start_link/2, run/2, cancel/1, is_running/1]).

%% gen_server callbacks
-export([init/1, terminate/2, code_change/3]).
Expand All @@ -40,13 +40,6 @@ run(Pid, IdxState) ->
gen_server:call(Pid, {compact, IdxState}).


monitor(Pid) ->
case gen_server:call(Pid, get_pid) of
{ok, undefined} -> {error, compaction_not_running};
{ok, CPid} -> {ok, erlang:monitor(process, CPid)}
end.


cancel(Pid) ->
gen_server:call(Pid, cancel).

Expand All @@ -66,12 +59,10 @@ terminate(_Reason, State) ->


handle_call({compact, _}, _From, #st{pid=Pid}=State) when is_pid(Pid) ->
{reply, ok, State};
{reply, {ok, Pid}, State};
handle_call({compact, IdxState}, _From, #st{idx=Idx}=State) ->
Pid = spawn_link(fun() -> compact(Idx, State#st.mod, IdxState) end),
{reply, ok, State#st{pid=Pid}};
handle_call(get_pid, _From, State) ->
{reply, {ok, State#st.pid}, State};
{reply, {ok, Pid}, State#st{pid=Pid}};
handle_call(cancel, _From, #st{pid=undefined}=State) ->
{reply, ok, State};
handle_call(cancel, _From, #st{pid=Pid}=State) ->
Expand Down
12 changes: 5 additions & 7 deletions src/couch_mrview/src/couch_mrview.erl
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
-export([query_all_docs/2, query_all_docs/4]).
-export([query_view/3, query_view/4, query_view/6]).
-export([get_info/2]).
-export([compact/2, monitor_compaction/2, cancel_compaction/2]).
-export([compact/2, compact/3, cancel_compaction/2]).
-export([cleanup/1]).

-include("couch_db.hrl").
Expand Down Expand Up @@ -93,14 +93,12 @@ get_info(Db, DDoc) ->


compact(Db, DDoc) ->
{ok, Pid} = couch_index_server:get_index(couch_mrview_index, Db, DDoc),
couch_index:compact(Pid).
compact(Db, DDoc, []).


monitor_compaction(Db, DDoc) ->
{ok, IPid} = couch_index_server:get_index(couch_mrview_index, Db, DDoc),
{ok, CPid} = couch_index:get_compactor_pid(IPid),
couch_index_compactor:monitor(CPid).
compact(Db, DDoc, Opts) ->
{ok, Pid} = couch_index_server:get_index(couch_mrview_index, Db, DDoc),
couch_index:compact(Pid, Opts).


cancel_compaction(Db, DDoc) ->
Expand Down
3 changes: 1 addition & 2 deletions src/couchdb/couch_compaction_daemon.erl
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,7 @@ maybe_compact_view(DbName, GroupId, Config) ->
{ok, GroupInfo} ->
case can_view_compact(Config, DbName, GroupId, GroupInfo) of
true ->
ok = couch_mrview:compact(DbName, DDocId),
{ok, MonRef} = couch_mrview:monitor_compaction(DbName, DDocId),
{ok, MonRef} = couch_mrview:compact(DbName, DDocId, [monitor]),
TimeLeft = compact_time_left(Config),
receive
{'DOWN', MonRef, process, _, normal} ->
Expand Down

0 comments on commit 3f2e857

Please sign in to comment.