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 2009/11/03 21:51:05 UTC
svn commit: r832550 - in /couchdb/trunk: ./ etc/couchdb/
share/www/script/test/ src/couchdb/ test/etap/
Author: damien
Date: Tue Nov 3 20:51:04 2009
New Revision: 832550
URL: http://svn.apache.org/viewvc?rev=832550&view=rev
Log:
Added batching of multiple updating requests, to improve throughput with many writers. Also removed the couch_batch_save module, now batch requests are simply saved async as immediately, batching with outhr updates if possible.
Removed:
couchdb/trunk/src/couchdb/couch_batch_save.erl
couchdb/trunk/src/couchdb/couch_batch_save_sup.erl
Modified:
couchdb/trunk/README
couchdb/trunk/etc/couchdb/default.ini.tpl.in
couchdb/trunk/share/www/script/test/batch_save.js
couchdb/trunk/src/couchdb/Makefile.am
couchdb/trunk/src/couchdb/couch.app.tpl.in
couchdb/trunk/src/couchdb/couch_db.erl
couchdb/trunk/src/couchdb/couch_db_updater.erl
couchdb/trunk/src/couchdb/couch_httpd_db.erl
couchdb/trunk/test/etap/001-load.t
Modified: couchdb/trunk/README
URL: http://svn.apache.org/viewvc/couchdb/trunk/README?rev=832550&r1=832549&r2=832550&view=diff
==============================================================================
--- couchdb/trunk/README (original)
+++ couchdb/trunk/README Tue Nov 3 20:51:04 2009
@@ -452,7 +452,7 @@
# Current time local 2009-09-26 23:47:44
# Using etap version "0.3.4"
1..39
- ok 1 - Loaded: couch_batch_save
+ ok 1 - Loaded: couch_btree
...
Cryptographic Software Notice
Modified: couchdb/trunk/etc/couchdb/default.ini.tpl.in
URL: http://svn.apache.org/viewvc/couchdb/trunk/etc/couchdb/default.ini.tpl.in?rev=832550&r1=832549&r2=832550&view=diff
==============================================================================
--- couchdb/trunk/etc/couchdb/default.ini.tpl.in (original)
+++ couchdb/trunk/etc/couchdb/default.ini.tpl.in Tue Nov 3 20:51:04 2009
@@ -48,7 +48,6 @@
view_manager={couch_view, start_link, []}
external_manager={couch_external_manager, start_link, []}
db_update_notifier={couch_db_update_notifier_sup, start_link, []}
-batch_save={couch_batch_save_sup, start_link, []}
query_servers={couch_query_servers, start_link, []}
httpd={couch_httpd, start_link, []}
stats_aggregator={couch_stats_aggregator, start, []}
Modified: couchdb/trunk/share/www/script/test/batch_save.js
URL: http://svn.apache.org/viewvc/couchdb/trunk/share/www/script/test/batch_save.js?rev=832550&r1=832549&r2=832550&view=diff
==============================================================================
--- couchdb/trunk/share/www/script/test/batch_save.js (original)
+++ couchdb/trunk/share/www/script/test/batch_save.js Tue Nov 3 20:51:04 2009
@@ -16,45 +16,30 @@
db.createDb();
if (debug) debugger;
- // commit should work fine with no batches
- T(db.ensureFullCommit().ok);
-
- // PUT a doc with ?batch=ok
- T(db.save({_id:"0",a:1,b:1}, {batch : "ok"}).ok);
-
- // test that response is 202 Accepted
- T(db.last_req.status == 202);
-
- T(db.allDocs().total_rows == 0);
-
- restartServer();
-
- // lost the updates
- T(db.allDocs().total_rows == 0);
-
- T(db.save({_id:"0",a:1,b:1}, {batch : "ok"}).ok);
- T(db.save({_id:"1",a:1,b:1}, {batch : "ok"}).ok);
- T(db.save({_id:"2",a:1,b:1}, {batch : "ok"}).ok);
-
- T(db.ensureFullCommit().ok);
- T(db.allDocs().total_rows == 3);
+ var i
+ for(i=0; i < 100; i++) {
+ T(db.save({_id:i.toString(),a:i,b:i}, {batch : "ok"}).ok);
+
+ // test that response is 202 Accepted
+ T(db.last_req.status == 202);
+ }
+
+ for(i=0; i < 100; i++) {
+ // attempt to save the same document a bunch of times
+ T(db.save({_id:"foo",a:i,b:i}, {batch : "ok"}).ok);
+
+ // test that response is 202 Accepted
+ T(db.last_req.status == 202);
+ }
+
+ while(db.allDocs().total_rows != 101){};
// repeat the tests for POST
- var resp = db.request("POST", db.uri + "?batch=ok", {body: JSON.stringify({a:1})});
- T(JSON.parse(resp.responseText).ok);
-
- // test that response is 202 Accepted
- T(resp.status == 202);
-
- T(db.allDocs().total_rows == 3);
- // restartServer();
- // // lost the POSTed doc
- // T(db.allDocs().total_rows == 3);
-
- var resp = db.request("POST", db.uri + "?batch=ok", {body: JSON.stringify({a:1})});
- T(JSON.parse(resp.responseText).ok);
-
- T(db.ensureFullCommit().ok);
- T(db.allDocs().total_rows == 5);
+ for(i=0; i < 100; i++) {
+ var resp = db.request("POST", db.uri + "?batch=ok", {body: JSON.stringify({a:1})});
+ T(JSON.parse(resp.responseText).ok);
+ }
+
+ while(db.allDocs().total_rows != 201){};
};
Modified: couchdb/trunk/src/couchdb/Makefile.am
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/Makefile.am?rev=832550&r1=832549&r2=832550&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/Makefile.am (original)
+++ couchdb/trunk/src/couchdb/Makefile.am Tue Nov 3 20:51:04 2009
@@ -56,8 +56,6 @@
couch.erl \
couch_app.erl \
couch_btree.erl \
- couch_batch_save.erl \
- couch_batch_save_sup.erl \
couch_config.erl \
couch_config_writer.erl \
couch_db.erl \
@@ -113,8 +111,6 @@
couch.beam \
couch_app.beam \
couch_btree.beam \
- couch_batch_save.beam \
- couch_batch_save_sup.beam \
couch_config.beam \
couch_config_writer.beam \
couch_db.beam \
Modified: couchdb/trunk/src/couchdb/couch.app.tpl.in
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch.app.tpl.in?rev=832550&r1=832549&r2=832550&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch.app.tpl.in (original)
+++ couchdb/trunk/src/couchdb/couch.app.tpl.in Tue Nov 3 20:51:04 2009
@@ -3,8 +3,6 @@
{vsn, "@version@"},
{modules, [@modules@]},
{registered, [
- couch_batch_save,
- couch_batch_save_sup,
couch_config,
couch_db_update,
couch_db_update_notifier_sup,
Modified: couchdb/trunk/src/couchdb/couch_db.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_db.erl?rev=832550&r1=832549&r2=832550&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_db.erl (original)
+++ couchdb/trunk/src/couchdb/couch_db.erl Tue Nov 3 20:51:04 2009
@@ -586,25 +586,46 @@
[full_commit|Options]
end.
+collect_results(UpdatePid, MRef, ResultsAcc) ->
+ receive
+ {result, UpdatePid, Result} ->
+ collect_results(UpdatePid, MRef, [Result | ResultsAcc]);
+ {done, UpdatePid} ->
+ {ok, ResultsAcc};
+ {retry, UpdatePid} ->
+ retry;
+ {'DOWN', MRef, _, _, Reason} ->
+ exit(Reason)
+ end.
+
write_and_commit(#db{update_pid=UpdatePid, user_ctx=Ctx}=Db, DocBuckets,
NonRepDocs, Options0) ->
Options = set_commit_option(Options0),
- case gen_server:call(UpdatePid,
- {update_docs, DocBuckets, NonRepDocs, Options}, infinity) of
- {ok, Results} -> {ok, Results};
- retry ->
- % This can happen if the db file we wrote to was swapped out by
- % compaction. Retry by reopening the db and writing to the current file
- {ok, Db2} = open_ref_counted(Db#db.main_pid, Ctx),
- DocBuckets2 = [[doc_flush_atts(Doc, Db2#db.fd) || Doc <- Bucket] || Bucket <- DocBuckets],
- % We only retry once
- close(Db2),
- case gen_server:call(UpdatePid, {update_docs, DocBuckets2, NonRepDocs, Options}, infinity) of
+ MergeConflicts = lists:member(merge_conflicts, Options),
+ FullCommit = lists:member(full_commit, Options),
+ MRef = erlang:monitor(process, UpdatePid),
+ try
+ UpdatePid ! {update_docs, self(), DocBuckets, NonRepDocs, MergeConflicts, FullCommit},
+ case collect_results(UpdatePid, MRef, []) of
{ok, Results} -> {ok, Results};
- retry -> throw({update_error, compaction_retry})
+ retry ->
+ % This can happen if the db file we wrote to was swapped out by
+ % compaction. Retry by reopening the db and writing to the current file
+ {ok, Db2} = open_ref_counted(Db#db.main_pid, Ctx),
+ DocBuckets2 = [[doc_flush_atts(Doc, Db2#db.fd) || Doc <- Bucket] || Bucket <- DocBuckets],
+ % We only retry once
+ close(Db2),
+ UpdatePid ! {update_docs, self(), DocBuckets2, NonRepDocs, MergeConflicts, FullCommit},
+ case collect_results(UpdatePid, MRef, []) of
+ {ok, Results} -> {ok, Results};
+ retry -> throw({update_error, compaction_retry})
+ end
end
+ after
+ erlang:demonitor(MRef, [flush])
end.
+
set_new_att_revpos(#doc{revs={RevPos,_Revs},atts=Atts}=Doc) ->
Doc#doc{atts= lists:map(fun(#att{data={_Fd,_Sp}}=Att) ->
% already commited to disk, do not set new rev
Modified: couchdb/trunk/src/couchdb/couch_db_updater.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_db_updater.erl?rev=832550&r1=832549&r2=832550&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_db_updater.erl (original)
+++ couchdb/trunk/src/couchdb/couch_db_updater.erl Tue Nov 3 20:51:04 2009
@@ -43,19 +43,6 @@
handle_call(get_db, _From, Db) ->
{reply, {ok, Db}, Db};
-handle_call({update_docs, GroupedDocs, NonRepDocs, Options}, _From, Db) ->
- try update_docs_int(Db, GroupedDocs, NonRepDocs, Options) of
- {ok, Failures, Db2} ->
- ok = gen_server:call(Db#db.main_pid, {db_updated, Db2}),
- if Db2#db.update_seq /= Db#db.update_seq ->
- couch_db_update_notifier:notify({updated, Db2#db.name});
- true -> ok
- end,
- {reply, {ok, Failures}, Db2}
- catch
- throw: retry ->
- {reply, retry, Db}
- end;
handle_call(full_commit, _From, #db{waiting_delayed_commit=nil}=Db) ->
{reply, ok, Db}; % no data waiting, return ok immediately
handle_call(full_commit, _From, Db) ->
@@ -192,6 +179,63 @@
{noreply, Db2}
end.
+
+merge_updates([], RestB, AccOutGroups) ->
+ lists:reverse(AccOutGroups, RestB);
+merge_updates(RestA, [], AccOutGroups) ->
+ lists:reverse(AccOutGroups, RestA);
+merge_updates([[{_, #doc{id=IdA}}|_]=GroupA | RestA],
+ [[{_, #doc{id=IdB}}|_]=GroupB | RestB], AccOutGroups) ->
+ if IdA == IdB ->
+ merge_updates(RestA, RestB, [GroupA ++ GroupB | AccOutGroups]);
+ IdA < IdB ->
+ merge_updates(RestA, [GroupB | RestB], [GroupA | AccOutGroups]);
+ true ->
+ merge_updates([GroupA | RestA], RestB, [GroupB | AccOutGroups])
+ end.
+
+collect_updates(GroupedDocsAcc, ClientsAcc, MergeConflicts, FullCommit) ->
+ receive
+ % only collect updates with the same MergeConflicts flag and without
+ % local docs. Makes it easier to avoid multiple local doc updaters.
+ {update_docs, Client, GroupedDocs, [], MergeConflicts, FullCommit2} ->
+ GroupedDocs2 = [[{Client, Doc} || Doc <- DocGroup]
+ || DocGroup <- GroupedDocs],
+ GroupedDocsAcc2 =
+ merge_updates(GroupedDocsAcc, GroupedDocs2, []),
+ collect_updates(GroupedDocsAcc2, [Client | ClientsAcc],
+ MergeConflicts, (FullCommit or FullCommit2))
+ after 0 ->
+ {GroupedDocsAcc, ClientsAcc, FullCommit}
+ end.
+
+handle_info({update_docs, Client, GroupedDocs, NonRepDocs, MergeConflicts,
+ FullCommit}, Db) ->
+ GroupedDocs2 = [[{Client, D} || D <- DocGroup] || DocGroup <- GroupedDocs],
+ if NonRepDocs == [] ->
+ {GroupedDocs3, Clients, FullCommit2} = collect_updates(GroupedDocs2,
+ [Client], MergeConflicts, FullCommit);
+ true ->
+ GroupedDocs3 = GroupedDocs2,
+ FullCommit2 = FullCommit,
+ Clients = [Client]
+ end,
+ NonRepDocs2 = [{Client, NRDoc} || NRDoc <- NonRepDocs],
+ try update_docs_int(Db, GroupedDocs3, NonRepDocs2, MergeConflicts,
+ FullCommit2) of
+ {ok, Db2} ->
+ ok = gen_server:call(Db#db.main_pid, {db_updated, Db2}),
+ if Db2#db.update_seq /= Db#db.update_seq ->
+ couch_db_update_notifier:notify({updated, Db2#db.name});
+ true -> ok
+ end,
+ [catch(ClientPid ! {done, self()}) || ClientPid <- Clients],
+ {noreply, Db2}
+ catch
+ throw: retry ->
+ [catch(ClientPid ! {retry, self()}) || ClientPid <- Clients],
+ {noreply, Db}
+ end;
handle_info(delayed_commit, Db) ->
{noreply, commit_data(Db)}.
@@ -399,18 +443,24 @@
end, Unflushed),
flush_trees(Db, RestUnflushed, [InfoUnflushed#full_doc_info{rev_tree=Flushed} | AccFlushed]).
-merge_rev_trees(_MergeConflicts, [], [], AccNewInfos, AccRemoveSeqs, AccConflicts, AccSeq) ->
- {ok, lists:reverse(AccNewInfos), AccRemoveSeqs, AccConflicts, AccSeq};
+
+send_result(Client, Id, OriginalRevs, NewResult) ->
+ % used to send a result to the client
+ catch(Client ! {result, self(), {{Id, OriginalRevs}, NewResult}}).
+
+merge_rev_trees(_MergeConflicts, [], [], AccNewInfos, AccRemoveSeqs, AccSeq) ->
+ {ok, lists:reverse(AccNewInfos), AccRemoveSeqs, AccSeq};
merge_rev_trees(MergeConflicts, [NewDocs|RestDocsList],
- [OldDocInfo|RestOldInfo], AccNewInfos, AccRemoveSeqs, AccConflicts, AccSeq) ->
+ [OldDocInfo|RestOldInfo], AccNewInfos, AccRemoveSeqs, AccSeq) ->
#full_doc_info{id=Id,rev_tree=OldTree,deleted=OldDeleted,update_seq=OldSeq}
= OldDocInfo,
- {NewRevTree, NewConflicts} = lists:foldl(
- fun(#doc{revs={Pos,[_Rev|PrevRevs]}}=NewDoc, {AccTree, AccConflicts2}) ->
+ NewRevTree = lists:foldl(
+ fun({Client, #doc{revs={Pos,[_Rev|PrevRevs]}}=NewDoc}, AccTree) ->
if not MergeConflicts ->
case couch_key_tree:merge(AccTree, [couch_db:doc_to_tree(NewDoc)]) of
{_NewTree, conflicts} when (not OldDeleted) ->
- {AccTree, [{{Id, {Pos-1,PrevRevs}}, conflict} | AccConflicts2]};
+ send_result(Client, Id, {Pos-1,PrevRevs}, conflict),
+ AccTree;
{NewTree, no_conflicts} when AccTree == NewTree ->
% the tree didn't change at all
% meaning we are saving a rev that's already
@@ -426,26 +476,28 @@
NewDoc2 = NewDoc#doc{revs={OldPos + 1, [NewRevId, OldRev]}},
{NewTree2, _} = couch_key_tree:merge(AccTree,
[couch_db:doc_to_tree(NewDoc2)]),
- % we changed the rev id, this tells the caller we did.
- {NewTree2, [{{Id, {Pos-1,PrevRevs}}, {ok, {OldPos + 1, NewRevId}}}
- | AccConflicts2]};
+ % we changed the rev id, this tells the caller we did
+ send_result(Client, Id, {Pos-1,PrevRevs},
+ {ok, {OldPos + 1, NewRevId}}),
+ NewTree2;
true ->
- {AccTree, [{{Id, {Pos-1,PrevRevs}}, conflict} | AccConflicts2]}
+ send_result(Client, Id, {Pos-1,PrevRevs}, conflict),
+ AccTree
end;
{NewTree, _} ->
- {NewTree, AccConflicts2}
+ NewTree
end;
true ->
{NewTree, _} = couch_key_tree:merge(AccTree,
[couch_db:doc_to_tree(NewDoc)]),
- {NewTree, AccConflicts2}
+ NewTree
end
end,
- {OldTree, AccConflicts}, NewDocs),
+ OldTree, NewDocs),
if NewRevTree == OldTree ->
% nothing changed
merge_rev_trees(MergeConflicts, RestDocsList, RestOldInfo, AccNewInfos,
- AccRemoveSeqs, NewConflicts, AccSeq);
+ AccRemoveSeqs, AccSeq);
true ->
% we have updated the document, give it a new seq #
NewInfo = #full_doc_info{id=Id,update_seq=AccSeq+1,rev_tree=NewRevTree},
@@ -454,7 +506,7 @@
_ -> [OldSeq | AccRemoveSeqs]
end,
merge_rev_trees(MergeConflicts, RestDocsList, RestOldInfo,
- [NewInfo|AccNewInfos], RemoveSeqs, NewConflicts, AccSeq+1)
+ [NewInfo|AccNewInfos], RemoveSeqs, AccSeq+1)
end.
@@ -473,13 +525,13 @@
[Info#full_doc_info{rev_tree=couch_key_tree:stem(Tree, Limit)} ||
#full_doc_info{rev_tree=Tree}=Info <- DocInfos].
-update_docs_int(Db, DocsList, NonRepDocs, Options) ->
+update_docs_int(Db, DocsList, NonRepDocs, MergeConflicts, FullCommit) ->
#db{
fulldocinfo_by_id_btree = DocInfoByIdBTree,
docinfo_by_seq_btree = DocInfoBySeqBTree,
update_seq = LastSeq
} = Db,
- Ids = [Id || [#doc{id=Id}|_] <- DocsList],
+ Ids = [Id || [{_Client, #doc{id=Id}}|_] <- DocsList],
% lookup up the old documents, if they exist.
OldDocLookups = couch_btree:lookup(DocInfoByIdBTree, Ids),
OldDocInfos = lists:zipwith(
@@ -489,17 +541,15 @@
#full_doc_info{id=Id}
end,
Ids, OldDocLookups),
-
% Merge the new docs into the revision trees.
- {ok, NewDocInfos0, RemoveSeqs, Conflicts, NewSeq} = merge_rev_trees(
- lists:member(merge_conflicts, Options),
- DocsList, OldDocInfos, [], [], [], LastSeq),
+ {ok, NewDocInfos0, RemoveSeqs, NewSeq} = merge_rev_trees(
+ MergeConflicts, DocsList, OldDocInfos, [], [], LastSeq),
NewFullDocInfos = stem_full_doc_infos(Db, NewDocInfos0),
% All documents are now ready to write.
- {ok, LocalConflicts, Db2} = update_local_docs(Db, NonRepDocs),
+ {ok, Db2} = update_local_docs(Db, NonRepDocs),
% Write out the document summaries (the bodies are stored in the nodes of
% the trees, the attachments are already written to disk)
@@ -526,15 +576,14 @@
Db4 = refresh_validate_doc_funs(Db3)
end,
- {ok, LocalConflicts ++ Conflicts,
- commit_data(Db4, not lists:member(full_commit, Options))}.
+ {ok, commit_data(Db4, not FullCommit)}.
update_local_docs(#db{local_docs_btree=Btree}=Db, Docs) ->
- Ids = [Id || #doc{id=Id} <- Docs],
+ Ids = [Id || {_Client, #doc{id=Id}} <- Docs],
OldDocLookups = couch_btree:lookup(Btree, Ids),
BtreeEntries = lists:zipwith(
- fun(#doc{id=Id,deleted=Delete,revs={0,PrevRevs},body=Body}, OldDocLookup) ->
+ fun({Client, #doc{id=Id,deleted=Delete,revs={0,PrevRevs},body=Body}}, OldDocLookup) ->
case PrevRevs of
[RevStr|_] ->
PrevRev = list_to_integer(?b2l(RevStr));
@@ -549,28 +598,28 @@
case OldRev == PrevRev of
true ->
case Delete of
- false -> {update, {Id, {PrevRev + 1, PrevRevs, Body}}};
- true -> {remove, Id, PrevRevs}
+ false ->
+ send_result(Client, Id, {0, PrevRevs}, {ok,
+ {0, ?l2b(integer_to_list(PrevRev + 1))}}),
+ {update, {Id, {PrevRev + 1, Body}}};
+ true ->
+ send_result(Client, Id, {0, PrevRevs},
+ {ok, {0, <<"0">>}}),
+ {remove, Id}
end;
false ->
- {conflict, {Id, {0, PrevRevs}}}
+ send_result(Client, Id, {0, PrevRevs}, conflict),
+ ignore
end
end, Docs, OldDocLookups),
- BtreeIdsRemove = [Id || {remove, Id, _PrevRevs} <- BtreeEntries],
- BtreeIdsUpdate = [{Id, {NewRev, Body}} || {update, {Id, {NewRev, _OldRevs, Body}}} <- BtreeEntries],
- Results =
- [{{Id, {0, PrevRevs}}, {ok, {0, <<"0">>}}}
- || {remove, Id, PrevRevs} <- BtreeEntries] ++
- [{{Id, {0, PrevRevs}}, {ok, {0, ?l2b(integer_to_list(NewRev))}}}
- || {update, {Id, {NewRev, PrevRevs, _Body}}} <- BtreeEntries] ++
- [{IdRevs, conflict}
- || {conflict, IdRevs} <- BtreeEntries],
+ BtreeIdsRemove = [Id || {remove, Id} <- BtreeEntries],
+ BtreeIdsUpdate = [{Key, Val} || {update, {Key, Val}} <- BtreeEntries],
{ok, Btree2} =
couch_btree:add_remove(Btree, BtreeIdsUpdate, BtreeIdsRemove),
- {ok, Results, Db#db{local_docs_btree = Btree2}}.
+ {ok, Db#db{local_docs_btree = Btree2}}.
commit_data(Db) ->
Modified: couchdb/trunk/src/couchdb/couch_httpd_db.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_httpd_db.erl?rev=832550&r1=832549&r2=832550&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_httpd_db.erl (original)
+++ couchdb/trunk/src/couchdb/couch_httpd_db.erl Tue Nov 3 20:51:04 2009
@@ -349,9 +349,15 @@
DocId = Doc2#doc.id,
case couch_httpd:qs_value(Req, "batch") of
"ok" ->
- % batch
- ok = couch_batch_save:eventually_save_doc(
- Db#db.name, Doc2, Db#db.user_ctx),
+ % async_batching
+ spawn(fun() ->
+ case catch(couch_db:update_doc(Db, Doc2, [])) of
+ {ok, _} -> ok;
+ Error ->
+ ?LOG_INFO("Batch doc error (~s): ~p",[DocId, Error])
+ end
+ end),
+
send_json(Req, 202, [], {[
{ok, true},
{id, DocId}
@@ -378,7 +384,6 @@
{ok, StartTime} =
case couch_httpd:qs_value(Req, "seq") of
undefined ->
- committed = couch_batch_save:commit_now(Db#db.name, Db#db.user_ctx),
couch_db:ensure_full_commit(Db);
RequiredStr ->
RequiredSeq = list_to_integer(RequiredStr),
@@ -749,7 +754,14 @@
"ok" ->
% batch
Doc = couch_doc_from_req(Req, DocId, Json),
- ok = couch_batch_save:eventually_save_doc(Db#db.name, Doc, Db#db.user_ctx),
+
+ spawn(fun() ->
+ case catch(couch_db:update_doc(Db, Doc, [])) of
+ {ok, _} -> ok;
+ Error ->
+ ?LOG_INFO("Batch doc error (~s): ~p",[DocId, Error])
+ end
+ end),
send_json(Req, 202, [], {[
{ok, true},
{id, DocId}
Modified: couchdb/trunk/test/etap/001-load.t
URL: http://svn.apache.org/viewvc/couchdb/trunk/test/etap/001-load.t?rev=832550&r1=832549&r2=832550&view=diff
==============================================================================
--- couchdb/trunk/test/etap/001-load.t (original)
+++ couchdb/trunk/test/etap/001-load.t Tue Nov 3 20:51:04 2009
@@ -21,8 +21,6 @@
code:add_pathz("src/couchdb"),
etap:plan(39),
Modules = [
- couch_batch_save,
- couch_batch_save_sup,
couch_btree,
couch_config,
couch_config_writer,