Author: davisp
Date: Sun Sep 18 21:52:09 2011
New Revision: 1172378
URL: http://svn.apache.org/viewvc?rev=1172378&view=rev
Log:
Avoid a race condition for monitored compaction.
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.
Modified:
couchdb/trunk/src/couch_index/src/couch_index.erl
couchdb/trunk/src/couch_index/src/couch_index_compactor.erl
couchdb/trunk/src/couch_mrview/src/couch_mrview.erl
couchdb/trunk/src/couchdb/couch_compaction_daemon.erl
Modified: couchdb/trunk/src/couch_index/src/couch_index.erl
URL:
http://svn.apache.org/viewvc/couchdb/trunk/src/couch_index/src/couch_index.erl?rev=1172378&r1=1172377&r2=1172378&view=diff
==============================================================================
--- couchdb/trunk/src/couch_index/src/couch_index.erl (original)
+++ couchdb/trunk/src/couch_index/src/couch_index.erl Sun Sep 18 21:52:09 2011
@@ -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
@@ -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) ->
@@ -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) ->
Modified: couchdb/trunk/src/couch_index/src/couch_index_compactor.erl
URL:
http://svn.apache.org/viewvc/couchdb/trunk/src/couch_index/src/couch_index_compactor.erl?rev=1172378&r1=1172377&r2=1172378&view=diff
==============================================================================
--- couchdb/trunk/src/couch_index/src/couch_index_compactor.erl (original)
+++ couchdb/trunk/src/couch_index/src/couch_index_compactor.erl Sun Sep 18
21:52:09 2011
@@ -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]).
@@ -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).
@@ -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) ->
Modified: couchdb/trunk/src/couch_mrview/src/couch_mrview.erl
URL:
http://svn.apache.org/viewvc/couchdb/trunk/src/couch_mrview/src/couch_mrview.erl?rev=1172378&r1=1172377&r2=1172378&view=diff
==============================================================================
--- couchdb/trunk/src/couch_mrview/src/couch_mrview.erl (original)
+++ couchdb/trunk/src/couch_mrview/src/couch_mrview.erl Sun Sep 18 21:52:09 2011
@@ -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").
@@ -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) ->
Modified: couchdb/trunk/src/couchdb/couch_compaction_daemon.erl
URL:
http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_compaction_daemon.erl?rev=1172378&r1=1172377&r2=1172378&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_compaction_daemon.erl (original)
+++ couchdb/trunk/src/couchdb/couch_compaction_daemon.erl Sun Sep 18 21:52:09
2011
@@ -228,8 +228,7 @@ maybe_compact_view(DbName, GroupId, Conf
{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} ->