diff options
author | Robert Newson <rnewson@apache.org> | 2020-11-05 17:20:12 +0000 |
---|---|---|
committer | Robert Newson <rnewson@apache.org> | 2020-11-05 17:43:52 +0000 |
commit | 0678742e4d0176807b221fb519c211a579c4baf2 (patch) | |
tree | 4dad6620980693a493678d2cab27c6e1058301c9 | |
parent | 077b09cb21dc8dbb6d52d8d81b2afc33bca835fe (diff) | |
download | couchdb-0678742e4d0176807b221fb519c211a579c4baf2.tar.gz |
Retry filter_docs sequentially if the patch exceeds couchjs stackchanges_filter_all_docs_oom_3.x
A document with lots of conflicts can blow up couchjs if the user
calls _changes with a javascript filter and with `style=all_docs` as
this option causes up to fetch all the conflicts.
All leaf revisions of the document are then passed in a single call to
ddoc_prompt, which can fail if there's a lot of them.
In that event, we simply try them sequentially and assemble the
response from each call.
Should be backported to 3.x
-rw-r--r-- | src/couch/src/couch_query_servers.erl | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/src/couch/src/couch_query_servers.erl b/src/couch/src/couch_query_servers.erl index 447daea61..6649df364 100644 --- a/src/couch/src/couch_query_servers.erl +++ b/src/couch/src/couch_query_servers.erl @@ -495,9 +495,21 @@ filter_docs(Req, Db, DDoc, FName, Docs) -> end, Options = json_doc_options(), JsonDocs = [json_doc(Doc, Options) || Doc <- Docs], + try + {ok, filter_docs_int(DDoc, FName, JsonReq, JsonDocs)} + catch + throw:{os_process_error,{exit_status,1}} -> + %% batch used too much memory, retry sequentially. + Fun = fun(JsonDoc) -> + filter_docs_int(DDoc, FName, JsonReq, [JsonDoc]) + end, + {ok, lists:flatmap(Fun, JsonDocs)} + end. + +filter_docs_int(DDoc, FName, JsonReq, JsonDocs) -> [true, Passes] = ddoc_prompt(DDoc, [<<"filters">>, FName], [JsonDocs, JsonReq]), - {ok, Passes}. + Passes. ddoc_proc_prompt({Proc, DDocId}, FunPath, Args) -> proc_prompt(Proc, [<<"ddoc">>, DDocId, FunPath, Args]). |