couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rand...@apache.org
Subject [3/3] git commit: Fix COUCHDB-1363 - race condition in couch_changes
Date Fri, 16 Dec 2011 01:00:29 GMT
Fix COUCHDB-1363 - race condition in couch_changes

It's necessary to re-open the #db after subscribing to notifications
so that updates are not lost. In practice, this is rarely problematic
because the next change will cause everything to catch up, but if a
quick burst of changes happens while replication is starting the
replication can go stale. Detected by intermittent replicator_db js
test failures.


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/1bbe6197
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/1bbe6197
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/1bbe6197

Branch: refs/heads/1.2.x
Commit: 1bbe61973a8d6b3a7c0d8789cdd01bb86499285d
Parents: 7f9376c
Author: Randall Leeds <randall@apache.org>
Authored: Wed Dec 14 20:12:08 2011 -0800
Committer: Randall Leeds <randall@apache.org>
Committed: Thu Dec 15 16:47:41 2011 -0800

----------------------------------------------------------------------
 src/couchdb/couch_changes.erl |   22 ++++++++++++++--------
 1 files changed, 14 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/1bbe6197/src/couchdb/couch_changes.erl
----------------------------------------------------------------------
diff --git a/src/couchdb/couch_changes.erl b/src/couchdb/couch_changes.erl
index 1de24d4..756a45a 100644
--- a/src/couchdb/couch_changes.erl
+++ b/src/couchdb/couch_changes.erl
@@ -35,7 +35,7 @@
 }).
 
 %% @type Req -> #httpd{} | {json_req, JsonObj()}
-handle_changes(Args1, Req, Db) ->
+handle_changes(Args1, Req, Db0) ->
     #changes_args{
         style = Style,
         filter = FilterName,
@@ -43,13 +43,17 @@ handle_changes(Args1, Req, Db) ->
         dir = Dir,
         since = Since
     } = Args1,
-    {FilterFun, FilterArgs} = make_filter_fun(FilterName, Style, Req, Db),
+    {FilterFun, FilterArgs} = make_filter_fun(FilterName, Style, Req, Db0),
     Args = Args1#changes_args{filter_fun = FilterFun, filter_args = FilterArgs},
-    StartSeq = case Dir of
-    rev ->
-        couch_db:get_update_seq(Db);
-    fwd ->
-        Since
+    Start = fun() ->
+        {ok, Db} = couch_db:reopen(Db0),
+        StartSeq = case Dir of
+        rev ->
+            couch_db:get_update_seq(Db);
+        fwd ->
+            Since
+        end,
+        {Db, StartSeq}
     end,
     % begin timer to deal with heartbeat when filter function fails
     case Args#changes_args.heartbeat of
@@ -64,12 +68,13 @@ handle_changes(Args1, Req, Db) ->
             {Callback, UserAcc} = get_callback_acc(CallbackAcc),
             Self = self(),
             {ok, Notify} = couch_db_update_notifier:start_link(
-                fun({_, DbName}) when DbName == Db#db.name ->
+                fun({_, DbName}) when  Db0#db.name == DbName ->
                     Self ! db_updated;
                 (_) ->
                     ok
                 end
             ),
+            {Db, StartSeq} = Start(),
             UserAcc2 = start_sending_changes(Callback, UserAcc, Feed),
             {Timeout, TimeoutFun} = get_changes_timeout(Args, Callback),
             Acc0 = build_acc(Args, Callback, UserAcc2, Db, StartSeq,
@@ -89,6 +94,7 @@ handle_changes(Args1, Req, Db) ->
             {Callback, UserAcc} = get_callback_acc(CallbackAcc),
             UserAcc2 = start_sending_changes(Callback, UserAcc, Feed),
             {Timeout, TimeoutFun} = get_changes_timeout(Args, Callback),
+            {Db, StartSeq} = Start(),
             Acc0 = build_acc(Args#changes_args{feed="normal"}, Callback,
                              UserAcc2, Db, StartSeq, <<>>, Timeout, TimeoutFun),
             {ok, #changes_acc{seq = LastSeq, user_acc = UserAcc3}} =


Mime
View raw message