You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by fd...@apache.org on 2011/12/05 20:57:56 UTC

[2/2] git commit: Add stats to replication docs

Add stats to replication docs

When a replication finishes, add its stats to the respective
document. These are the same stats as provided by the active
tasks API.

COUCHDB-1349


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

Branch: refs/heads/master
Commit: 72e2db8ccd2081eb7a1f7a78a857c3e7c33150e2
Parents: 8f38cbe
Author: Filipe David Borba Manana <fd...@apache.org>
Authored: Mon Dec 5 18:30:47 2011 +0000
Committer: Filipe David Borba Manana <fd...@apache.org>
Committed: Mon Dec 5 19:24:17 2011 +0000

----------------------------------------------------------------------
 share/www/script/test/replicator_db.js             |   52 +++++++++++++++
 src/couch_replicator/src/couch_replicator.erl      |   31 ++++++---
 .../src/couch_replicator_manager.erl               |   15 +++--
 src/couchdb/couch_doc.erl                          |    3 +
 4 files changed, 85 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/72e2db8c/share/www/script/test/replicator_db.js
----------------------------------------------------------------------
diff --git a/share/www/script/test/replicator_db.js b/share/www/script/test/replicator_db.js
index 46d3873..a51cce8 100644
--- a/share/www/script/test/replicator_db.js
+++ b/share/www/script/test/replicator_db.js
@@ -123,6 +123,17 @@ couchTests.replicator_db = function(debug) {
     T(repDoc1._replication_state === "completed", "simple");
     T(typeof repDoc1._replication_state_time === "string");
     T(typeof repDoc1._replication_id  === "string");
+    T(typeof repDoc1._replication_stats === "object", "doc has stats");
+    var stats = repDoc1._replication_stats;
+    TEquals(docs1.length, stats.revisions_checked,
+       "right # of revisions_checked");
+    TEquals(docs1.length, stats.missing_revisions_found,
+      "right # of missing_revisions_found");
+    TEquals(docs1.length, stats.docs_read, "right # of docs_read");
+    TEquals(docs1.length, stats.docs_written, "right # of docs_written");
+    TEquals(0, stats.doc_write_failures, "right # of doc_write_failures");
+    TEquals(dbA.info().update_seq, stats.checkpointed_source_seq,
+      "right checkpointed_source_seq");
   }
 
 
@@ -175,6 +186,15 @@ couchTests.replicator_db = function(debug) {
     T(repDoc1._replication_state === "completed", "filtered");
     T(typeof repDoc1._replication_state_time === "string");
     T(typeof repDoc1._replication_id  === "string");
+    T(typeof repDoc1._replication_stats === "object", "doc has stats");
+    var stats = repDoc1._replication_stats;
+    TEquals(2, stats.revisions_checked, "right # of revisions_checked");
+    TEquals(2, stats.missing_revisions_found, "right # of missing_revisions_found");
+    TEquals(2, stats.docs_read, "right # of docs_read");
+    TEquals(1, stats.docs_written, "right # of docs_written");
+    TEquals(1, stats.doc_write_failures, "right # of doc_write_failures");
+    TEquals(dbA.info().update_seq, stats.checkpointed_source_seq,
+      "right checkpointed_source_seq");
   }
 
 
@@ -305,6 +325,17 @@ couchTests.replicator_db = function(debug) {
 
     copy = dbB.open("_design/mydesign");
     T(copy === null);
+
+    repDoc = repDb.open(repDoc._id);
+    T(typeof repDoc._replication_stats === "object", "doc has stats");
+    var stats = repDoc._replication_stats;
+    TEquals(3, stats.revisions_checked, "right # of revisions_checked");
+    TEquals(3, stats.missing_revisions_found, "right # of missing_revisions_found");
+    TEquals(3, stats.docs_read, "right # of docs_read");
+    TEquals(2, stats.docs_written, "right # of docs_written");
+    TEquals(1, stats.doc_write_failures, "right # of doc_write_failures");
+    TEquals(dbA.info().update_seq, stats.checkpointed_source_seq,
+      "right checkpointed_source_seq");
   }
 
 
@@ -334,6 +365,17 @@ couchTests.replicator_db = function(debug) {
     T(repDoc1_copy._replication_state === "completed");
     T(typeof repDoc1_copy._replication_state_time === "string");
     T(typeof repDoc1_copy._replication_id  === "string");
+    T(typeof repDoc1_copy._replication_stats === "object", "doc has stats");
+    var stats = repDoc1_copy._replication_stats;
+    TEquals(docs1.length, stats.revisions_checked,
+      "right # of revisions_checked");
+    TEquals(docs1.length, stats.missing_revisions_found,
+      "right # of missing_revisions_found");
+    TEquals(docs1.length, stats.docs_read, "right # of docs_read");
+    TEquals(docs1.length, stats.docs_written, "right # of docs_written");
+    TEquals(0, stats.doc_write_failures, "right # of doc_write_failures");
+    TEquals(dbA.info().update_seq, stats.checkpointed_source_seq,
+      "right checkpointed_source_seq");
 
     var newDoc = {
       _id: "doc666",
@@ -366,6 +408,16 @@ couchTests.replicator_db = function(debug) {
     T(typeof repDoc2_copy._replication_state_time === "string");
     T(typeof repDoc2_copy._replication_id === "string");
     T(repDoc2_copy._replication_id === repDoc1_copy._replication_id);
+    T(typeof repDoc2_copy._replication_stats === "object", "doc has stats");
+    stats = repDoc2_copy._replication_stats;
+    TEquals(1, stats.revisions_checked, "right # of revisions_checked");
+    TEquals(1, stats.missing_revisions_found,
+      "right # of missing_revisions_found");
+    TEquals(1, stats.docs_read, "right # of docs_read");
+    TEquals(1, stats.docs_written, "right # of docs_written");
+    TEquals(0, stats.doc_write_failures, "right # of doc_write_failures");
+    TEquals(dbA.info().update_seq, stats.checkpointed_source_seq,
+      "right checkpointed_source_seq");
   }
 
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/72e2db8c/src/couch_replicator/src/couch_replicator.erl
----------------------------------------------------------------------
diff --git a/src/couch_replicator/src/couch_replicator.erl b/src/couch_replicator/src/couch_replicator.erl
index f321bf8..14f0e36 100644
--- a/src/couch_replicator/src/couch_replicator.erl
+++ b/src/couch_replicator/src/couch_replicator.erl
@@ -459,7 +459,7 @@ terminate(normal, #rep_state{rep_details = #rep{id = RepId} = Rep,
     checkpoint_history = CheckpointHistory} = State) ->
     terminate_cleanup(State),
     couch_replicator_notifier:notify({finished, RepId, CheckpointHistory}),
-    couch_replicator_manager:replication_completed(Rep);
+    couch_replicator_manager:replication_completed(Rep, rep_stats(State));
 
 terminate(shutdown, #rep_state{rep_details = #rep{id = RepId}} = State) ->
     % cancelled replication throught ?MODULE:cancel_replication/1
@@ -916,18 +916,11 @@ source_cur_seq(#rep_state{source = Db, source_seq = Seq}) ->
 update_task(State) ->
     #rep_state{
         current_through_seq = {_, CurSeq},
-        committed_seq = {_, CommittedSeq},
-        source_seq = SourceCurSeq,
-        stats = Stats
+        source_seq = SourceCurSeq
     } = State,
-    couch_task_status:update([
-        {revisions_checked, Stats#rep_stats.missing_checked},
-        {missing_revisions_found, Stats#rep_stats.missing_found},
-        {docs_read, Stats#rep_stats.docs_read},
-        {docs_written, Stats#rep_stats.docs_written},
-        {doc_write_failures, Stats#rep_stats.doc_write_failures},
+    couch_task_status:update(
+        rep_stats(State) ++ [
         {source_seq, SourceCurSeq},
-        {checkpointed_source_seq, CommittedSeq},
         case is_number(CurSeq) andalso is_number(SourceCurSeq) of
         true ->
             case SourceCurSeq of
@@ -940,3 +933,19 @@ update_task(State) ->
             {progress, null}
         end
     ]).
+
+
+rep_stats(State) ->
+    #rep_state{
+        committed_seq = {_, CommittedSeq},
+        stats = Stats
+    } = State,
+    [
+        {revisions_checked, Stats#rep_stats.missing_checked},
+        {missing_revisions_found, Stats#rep_stats.missing_found},
+        {docs_read, Stats#rep_stats.docs_read},
+        {docs_written, Stats#rep_stats.docs_written},
+        {doc_write_failures, Stats#rep_stats.doc_write_failures},
+        {checkpointed_source_seq, CommittedSeq}
+    ].
+

http://git-wip-us.apache.org/repos/asf/couchdb/blob/72e2db8c/src/couch_replicator/src/couch_replicator_manager.erl
----------------------------------------------------------------------
diff --git a/src/couch_replicator/src/couch_replicator_manager.erl b/src/couch_replicator/src/couch_replicator_manager.erl
index c61b27b..3d31fa8 100644
--- a/src/couch_replicator/src/couch_replicator_manager.erl
+++ b/src/couch_replicator/src/couch_replicator_manager.erl
@@ -14,7 +14,7 @@
 -behaviour(gen_server).
 
 % public API
--export([replication_started/1, replication_completed/1, replication_error/2]).
+-export([replication_started/1, replication_completed/2, replication_error/2]).
 
 % gen_server callbacks
 -export([start_link/0, init/1, handle_call/3, handle_info/2, handle_cast/2]).
@@ -63,19 +63,22 @@ replication_started(#rep{id = {BaseId, _} = RepId}) ->
     #rep_state{rep = #rep{doc_id = DocId}} ->
         update_rep_doc(DocId, [
             {<<"_replication_state">>, <<"triggered">>},
-            {<<"_replication_id">>, ?l2b(BaseId)}]),
+            {<<"_replication_id">>, ?l2b(BaseId)},
+            {<<"_replication_stats">>, undefined}]),
         ok = gen_server:call(?MODULE, {rep_started, RepId}, infinity),
         ?LOG_INFO("Document `~s` triggered replication `~s`",
             [DocId, pp_rep_id(RepId)])
     end.
 
 
-replication_completed(#rep{id = RepId}) ->
+replication_completed(#rep{id = RepId}, Stats) ->
     case rep_state(RepId) of
     nil ->
         ok;
     #rep_state{rep = #rep{doc_id = DocId}} ->
-        update_rep_doc(DocId, [{<<"_replication_state">>, <<"completed">>}]),
+        update_rep_doc(DocId, [
+            {<<"_replication_state">>, <<"completed">>},
+            {<<"_replication_stats">>, {Stats}}]),
         ok = gen_server:call(?MODULE, {rep_complete, RepId}, infinity),
         ?LOG_INFO("Replication `~s` finished (triggered by document `~s`)",
             [pp_rep_id(RepId), DocId])
@@ -516,7 +519,9 @@ update_rep_doc(RepDocId, KVs) ->
 
 update_rep_doc(RepDb, #doc{body = {RepDocBody}} = RepDoc, KVs) ->
     NewRepDocBody = lists:foldl(
-        fun({<<"_replication_state">> = K, State} = KV, Body) ->
+        fun({K, undefined}, Body) ->
+                lists:keydelete(K, 1, Body);
+            ({<<"_replication_state">> = K, State} = KV, Body) ->
                 case get_value(K, Body) of
                 State ->
                     Body;

http://git-wip-us.apache.org/repos/asf/couchdb/blob/72e2db8c/src/couchdb/couch_doc.erl
----------------------------------------------------------------------
diff --git a/src/couchdb/couch_doc.erl b/src/couchdb/couch_doc.erl
index 7199d07..b7c2a17 100644
--- a/src/couchdb/couch_doc.erl
+++ b/src/couchdb/couch_doc.erl
@@ -296,6 +296,9 @@ transfer_fields([{<<"_replication_state_time">>, _} = Field | Rest],
 transfer_fields([{<<"_replication_id">>, _} = Field | Rest],
     #doc{body=Fields} = Doc) ->
     transfer_fields(Rest, Doc#doc{body=[Field|Fields]});
+transfer_fields([{<<"_replication_stats">>, _} = Field | Rest],
+    #doc{body=Fields} = Doc) ->
+    transfer_fields(Rest, Doc#doc{body=[Field|Fields]});
 
 % unknown special field
 transfer_fields([{<<"_",Name/binary>>, _} | _], _) ->