summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Newson <rnewson@apache.org>2012-08-09 16:06:57 +0100
committerRobert Newson <rnewson@apache.org>2012-08-09 16:49:48 +0100
commitbde29bea6a4bdb5c73966524bd349335071262b5 (patch)
tree723ed10daa876592ad11f9b22457fe27475d7969
parent5ab712a235d51dfba78fa8c4bf29943f90062585 (diff)
downloadcouchdb-bde29bea6a4bdb5c73966524bd349335071262b5.tar.gz
Assert that index sig never changes in the lifetime of a couch index process
COUCHDB-1444 demonstrates that #st{} state get out of sync somehow, leading to unexpected 404's (missing_named_view) and 200's. This patch ensures that index sig never changes in the hope that it will lead to the cause of 1444 and prevent other occurrences of the same class of bug.
-rw-r--r--src/couch_index/src/couch_index.erl14
1 files changed, 13 insertions, 1 deletions
diff --git a/src/couch_index/src/couch_index.erl b/src/couch_index/src/couch_index.erl
index 508604829..5bf322e9f 100644
--- a/src/couch_index/src/couch_index.erl
+++ b/src/couch_index/src/couch_index.erl
@@ -171,6 +171,7 @@ handle_call({compacted, NewIdxState}, _From, State) ->
updater=Updater,
commit_delay=Delay
} = State,
+ assert_signature_match(Mod, OldIdxState, NewIdxState),
NewSeq = Mod:get(update_seq, NewIdxState),
OldSeq = Mod:get(update_seq, OldIdxState),
% For indices that require swapping files, we have to make sure we're
@@ -210,7 +211,12 @@ handle_cast({updated, NewIdxState}, State) ->
{noreply, NewState}
end;
handle_cast({new_state, NewIdxState}, State) ->
- #st{mod=Mod, commit_delay=Delay} = State,
+ #st{
+ mod=Mod,
+ idx_state=OldIdxState,
+ commit_delay=Delay
+ } = State,
+ assert_signature_match(Mod, OldIdxState, NewIdxState),
CurrSeq = Mod:get(update_seq, NewIdxState),
Args = [
Mod:get(db_name, NewIdxState),
@@ -323,3 +329,9 @@ send_replies(Waiters, UpdateSeq, IdxState) ->
{ToSend, Remaining} = lists:partition(Pred, Waiters),
[gen_server:reply(From, {ok, IdxState}) || {From, _} <- ToSend],
Remaining.
+
+assert_signature_match(Mod, OldIdxState, NewIdxState) ->
+ case {Mod:get(signature, OldIdxState), Mod:get(signature, NewIdxState)} of
+ {Sig, Sig} -> ok;
+ _ -> erlang:error(signature_mismatch)
+ end.