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 2012/08/14 22:19:00 UTC
git commit: COUCHDB-1444 Broken couch_view_group
Updated Branches:
refs/heads/1.2.x bb8397707 -> 53490d915
COUCHDB-1444 Broken couch_view_group
It appears that exit signals were propogating between couch_view_updater
processes through couch_os_process and friends. This changes the use of
the 'EXIT' signal to a '$gen_cast' message.
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/53490d91
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/53490d91
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/53490d91
Branch: refs/heads/1.2.x
Commit: 53490d915038c04ed47f0c8a00b771583c483b0e
Parents: bb83977
Author: Paul Joseph Davis <da...@apache.org>
Authored: Fri Aug 10 10:45:03 2012 -0500
Committer: Paul Joseph Davis <da...@apache.org>
Committed: Fri Aug 10 11:41:12 2012 -0500
----------------------------------------------------------------------
src/couchdb/couch_view_compactor.erl | 26 +++++++++---
src/couchdb/couch_view_group.erl | 63 ++++++++++++++---------------
src/couchdb/couch_view_updater.erl | 8 ++-
3 files changed, 56 insertions(+), 41 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/53490d91/src/couchdb/couch_view_compactor.erl
----------------------------------------------------------------------
diff --git a/src/couchdb/couch_view_compactor.erl b/src/couchdb/couch_view_compactor.erl
index 58600c8..a7dc68c 100644
--- a/src/couchdb/couch_view_compactor.erl
+++ b/src/couchdb/couch_view_compactor.erl
@@ -117,13 +117,27 @@ maybe_retry_compact(#db{name = DbName} = Db, GroupId, NewGroup) ->
couch_db:close(Db);
update ->
{ok, Db2} = couch_db:reopen(Db),
- {_, Ref} = erlang:spawn_monitor(fun() ->
- couch_view_updater:update(nil, NewGroup, Db2)
+ Self = self(),
+ {MPid, MRef} = erlang:spawn_monitor(fun() ->
+ couch_view_updater:update(Self, NewGroup, Db2)
end),
- receive
- {'DOWN', Ref, _, _, {new_group, NewGroup2}} ->
- maybe_retry_compact(Db2, GroupId, NewGroup2)
- end
+ NewGroup1 = get_new_group(MPid, MRef),
+ erlang:demonitor(MRef, [flush]),
+ maybe_retry_compact(Db2, GroupId, NewGroup1)
+ end.
+
+get_new_group(Pid, Ref) ->
+ receive
+ {'DOWN', Ref, _, _, {new_group, NewGroup}} ->
+ NewGroup;
+ {'DOWN', Ref, _, _, Reason} ->
+ erlang:error({view_compaction_error, Reason});
+ {'$gen_cast', {Pid, new_group, NewGroup}} ->
+ NewGroup;
+ {'$gen_cast', {partial_update, _, _}} ->
+ get_new_group(Pid, Ref);
+ Else ->
+ erlang:error({view_compaction_error, Else})
end.
%% @spec compact_view(View, EmptyView, Retry, Acc) -> {CompactView, NewAcc}
http://git-wip-us.apache.org/repos/asf/couchdb/blob/53490d91/src/couchdb/couch_view_group.erl
----------------------------------------------------------------------
diff --git a/src/couchdb/couch_view_group.erl b/src/couchdb/couch_view_group.erl
index fee2547..5f83c05 100644
--- a/src/couchdb/couch_view_group.erl
+++ b/src/couchdb/couch_view_group.erl
@@ -271,6 +271,37 @@ handle_cast({partial_update, Pid, #group{sig=GroupSig}=NewGroup}, #group_state{u
handle_cast({partial_update, _, _}, State) ->
%% message from an old (probably pre-compaction) updater; ignore
{noreply, State};
+handle_cast({FromPid, new_group, #group{sig=GroupSig} = Group},
+ #group_state{db_name=DbName,
+ group=#group{sig=GroupSig},
+ updater_pid=UpPid,
+ ref_counter=RefCounter,
+ waiting_list=WaitList,
+ shutdown=Shutdown,
+ waiting_commit=WaitingCommit}=State) when UpPid == FromPid ->
+ if not WaitingCommit ->
+ erlang:send_after(1000, self(), delayed_commit);
+ true -> ok
+ end,
+ case reply_with_group(Group, WaitList, [], RefCounter) of
+ [] ->
+ case Shutdown of
+ true ->
+ {stop, normal, State};
+ false ->
+ {noreply, State#group_state{waiting_commit=true, waiting_list=[],
+ group=Group, updater_pid=nil}}
+ end;
+ StillWaiting ->
+ % we still have some waiters, reopen the database and reupdate the index
+ Owner = self(),
+ Pid = spawn_link(fun() -> couch_view_updater:update(Owner, Group, DbName) end),
+ {noreply, State#group_state{waiting_commit=true,
+ waiting_list=StillWaiting, updater_pid=Pid}}
+ end;
+handle_cast({_, new_group, _}, State) ->
+ %% message from an old (probably pre-compaction) updater; ignore
+ {noreply, State};
handle_cast(ddoc_updated, State) ->
#group_state{
db_name = DbName,
@@ -317,38 +348,6 @@ handle_info(delayed_commit, #group_state{db_name=DbName,group=Group}=State) ->
{noreply, State#group_state{waiting_commit=true}}
end;
-handle_info({'EXIT', FromPid, {new_group, #group{sig=GroupSig} = Group}},
- #group_state{db_name=DbName,
- group=#group{sig=GroupSig},
- updater_pid=UpPid,
- ref_counter=RefCounter,
- waiting_list=WaitList,
- shutdown=Shutdown,
- waiting_commit=WaitingCommit}=State) when UpPid == FromPid ->
- if not WaitingCommit ->
- erlang:send_after(1000, self(), delayed_commit);
- true -> ok
- end,
- case reply_with_group(Group, WaitList, [], RefCounter) of
- [] ->
- case Shutdown of
- true ->
- {stop, normal, State};
- false ->
- {noreply, State#group_state{waiting_commit=true, waiting_list=[],
- group=Group, updater_pid=nil}}
- end;
- StillWaiting ->
- % we still have some waiters, reopen the database and reupdate the index
- Owner = self(),
- Pid = spawn_link(fun() -> couch_view_updater:update(Owner, Group, DbName) end),
- {noreply, State#group_state{waiting_commit=true,
- waiting_list=StillWaiting, updater_pid=Pid}}
- end;
-handle_info({'EXIT', _, {new_group, _}}, State) ->
- %% message from an old (probably pre-compaction) updater; ignore
- {noreply, State};
-
handle_info({'EXIT', UpPid, reset},
#group_state{init_args=InitArgs, updater_pid=UpPid} = State) ->
case prepare_group(InitArgs, true) of
http://git-wip-us.apache.org/repos/asf/couchdb/blob/53490d91/src/couchdb/couch_view_updater.erl
----------------------------------------------------------------------
diff --git a/src/couchdb/couch_view_updater.erl b/src/couchdb/couch_view_updater.erl
index 4aee586..6a5530e 100644
--- a/src/couchdb/couch_view_updater.erl
+++ b/src/couchdb/couch_view_updater.erl
@@ -92,9 +92,11 @@ update(Owner, Group, #db{name = DbName} = Db) ->
end,
ok, []),
couch_work_queue:close(MapQueue),
- receive {new_group, NewGroup} ->
- exit({new_group,
- NewGroup#group{current_seq=couch_db:get_update_seq(Db)}})
+ receive {new_group, NewGroup0} ->
+ NewGroup = NewGroup0#group{
+ current_seq=couch_db:get_update_seq(Db)
+ },
+ gen_server:cast(Owner, {self(), new_group, NewGroup})
end.