Permalink
Browse files

workaround to prevent the view changes reader to crage on non found doc

when a doc is removed from the database in the current version of the
view changes index, this change is not indexed and the view change index
has still the key indexed. The way to delete for now is to use
include_deleted=true and push deleted doc that match the view so the
deleted document can be indexed as deleted.

But when the doc is purged and someone fetch the changes the view
changes reader was crashing because it didn't find the doc. This
workaround patch the changes reader to ignore the documents not found
and simply log them.
  • Loading branch information...
1 parent e394ea3 commit e854dffb3bf20abef9efb4d44b0376cdc4f8228f @benoitc benoitc committed Sep 12, 2013
Showing with 39 additions and 21 deletions.
  1. +39 −21 apps/couch_changes/src/couch_changes.erl
@@ -544,29 +544,47 @@ view_changes_enumerator1(Id, Acc) ->
user_acc = UserAcc, limit = Limit, resp_type = ResponseType, db = Db,
timeout = Timeout, timeout_fun = TimeoutFun
} = Acc,
- {ok, DocInfo} = couch_db:get_doc_info(Db, Id),
- #doc_info{high_seq = Seq} = DocInfo,
- Results0 = FilterFun(Db, DocInfo),
- Results = [Result || Result <- Results0, Result /= null],
- Go = if (Limit =< 1) andalso Results =/= [] -> stop; true -> ok end,
- case Results of
- [] ->
- {Done, UserAcc2} = maybe_heartbeat(Timeout, TimeoutFun, UserAcc),
- case Done of
- stop ->
- {stop, Acc#changes_acc{seq = Seq, user_acc = UserAcc2}};
- ok ->
- {Go, Acc#changes_acc{seq = Seq, user_acc = UserAcc2}}
- end;
- _ ->
- ChangesRow = changes_row(Results, DocInfo, Acc),
- UserAcc2 = Callback({change, ChangesRow, Prepend}, ResponseType, UserAcc),
- reset_heartbeat(),
- {Go, Acc#changes_acc{
- seq = Seq, prepend = <<",\n">>,
- user_acc = UserAcc2, limit = Limit - 1}}
+
+ case couch_db:get_doc_info(Db, Id) of
+ {ok, DocInfo} ->
+ #doc_info{high_seq = Seq} = DocInfo,
+ Results0 = FilterFun(Db, DocInfo),
+ Results = [Result || Result <- Results0, Result /= null],
+ Go = if (Limit =< 1) andalso Results =/= [] -> stop;
+ true -> ok
+ end,
+ case Results of
+ [] ->
+ {Done, UserAcc2} = maybe_heartbeat(Timeout, TimeoutFun,
+ UserAcc),
+ case Done of
+ stop ->
+ {stop, Acc#changes_acc{seq = Seq, user_acc = UserAcc2}};
+ ok ->
+ {Go, Acc#changes_acc{seq = Seq, user_acc = UserAcc2}}
+ end;
+ _ ->
+ ChangesRow = changes_row(Results, DocInfo, Acc),
+ UserAcc2 = Callback({change, ChangesRow, Prepend},
+ ResponseType, UserAcc),
+ reset_heartbeat(),
+ {Go, Acc#changes_acc{
+ seq = Seq, prepend = <<",\n">>,
+ user_acc = UserAcc2, limit = Limit - 1}}
+ end;
+ Error ->
+ ?LOG_ERROR("view change error ignored: ~p", [Error]),
+ {Done, UserAcc2} = maybe_heartbeat(Timeout, TimeoutFun,
+ UserAcc),
+ case Done of
+ stop ->
+ {stop, Acc#changes_acc{user_acc = UserAcc2}};
+ ok ->
+ {ok, Acc#changes_acc{user_acc = UserAcc2}}
+ end
end.
+
changes_row(Results, DocInfo, Acc) ->
#doc_info{
id = Id, high_seq = Seq, revs = [#rev_info{deleted = Del} | _]

0 comments on commit e854dff

Please sign in to comment.