Fix multipart PUTs for document attachments Accidentally dropped some work for multipart attachments in clusters when we merged couch_att.erl
Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch/commit/28fdeb4f Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch/tree/28fdeb4f Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch/diff/28fdeb4f Branch: refs/heads/windsor-merge Commit: 28fdeb4f932f9e0f0fae59dbe89ef7e236e6e143 Parents: c484520 Author: Paul J. Davis <[email protected]> Authored: Sun Aug 10 17:32:52 2014 -0500 Committer: Robert Newson <[email protected]> Committed: Tue Aug 26 10:44:07 2014 +0100 ---------------------------------------------------------------------- src/couch_att.erl | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/28fdeb4f/src/couch_att.erl ---------------------------------------------------------------------- diff --git a/src/couch_att.erl b/src/couch_att.erl index e011402..720d435 100644 --- a/src/couch_att.erl +++ b/src/couch_att.erl @@ -527,6 +527,24 @@ flush_data(Fd, Fun, Att) when is_function(Fun) -> couch_db:with_stream(Fd, Att, fun(OutputStream) -> write_streamed_attachment(OutputStream, Fun, AttLen) end) + end; +flush_data(Fd, {follows, Parser, Ref}, Att) -> + ParserRef = erlang:monitor(process, Parser), + Fun = fun() -> + Parser ! {get_bytes, Ref, self()}, + receive + {started_open_doc_revs, NewRef} -> + couch_doc:restart_open_doc_revs(Parser, Ref, NewRef); + {bytes, Ref, Bytes} -> + Bytes; + {'DOWN', ParserRef, _, _, Reason} -> + throw({mp_parser_died, Reason}) + end + end, + try + flush_data(Fd, Fun, store(data, Fun, Att)) + after + erlang:demonitor(ParserRef, [flush]) end. @@ -564,7 +582,25 @@ foldl({Fd, Sp}, Att, Fun, Acc) -> couch_stream:foldl(Fd, Sp, Md5, Fun, Acc); foldl(DataFun, Att, Fun, Acc) when is_function(DataFun) -> Len = fetch(att_len, Att), - fold_streamed_data(DataFun, Len, Fun, Acc). + fold_streamed_data(DataFun, Len, Fun, Acc); +foldl({follows, Parser, Ref}, Att, Fun, Acc) -> + ParserRef = erlang:monitor(process, Parser), + DataFun = fun() -> + Parser ! {get_bytes, Ref, self()}, + receive + {started_open_doc_revs, NewRef} -> + couch_doc:restart_open_doc_revs(Parser, Ref, NewRef); + {bytes, Ref, Bytes} -> + Bytes; + {'DOWN', ParserRef, _, _, Reason} -> + throw({mp_parser_died, Reason}) + end + end, + try + foldl(DataFun, store(data, DataFun, Att), Fun, Acc) + after + erlang:demonitor(ParserRef, [flush]) + end. range_foldl(Att, From, To, Fun, Acc) ->
