This is an automated email from the ASF dual-hosted git repository. rnewson pushed a commit to branch fabric_teardown in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit 8343beb4c848766615adf4f2d724fedc8f9226a3 Author: Robert Newson <[email protected]> AuthorDate: Mon Aug 21 17:48:04 2023 +0100 Add deadline for starting a delayed response --- src/chttpd/src/chttpd.erl | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/chttpd/src/chttpd.erl b/src/chttpd/src/chttpd.erl index c8e6fdc97..4bec33d9e 100644 --- a/src/chttpd/src/chttpd.erl +++ b/src/chttpd/src/chttpd.erl @@ -90,7 +90,8 @@ headers, chunks, resp = nil, - buffer_response = false + buffer_response = false, + deadline }). -define(DEFAULT_SERVER_OPTIONS, "[{recbuf, undefined}]"). @@ -919,31 +920,31 @@ start_delayed_json_response(Req, Code, Headers) -> start_delayed_json_response(Req, Code, Headers, ""). start_delayed_json_response(Req, Code, Headers, FirstChunk) -> - {ok, #delayed_resp{ + {ok, start_deadline(#delayed_resp{ start_fun = fun start_json_response/3, req = Req, code = Code, headers = Headers, chunks = [FirstChunk], buffer_response = buffer_response(Req) - }}. + })}. start_delayed_chunked_response(Req, Code, Headers) -> start_delayed_chunked_response(Req, Code, Headers, ""). start_delayed_chunked_response(Req, Code, Headers, FirstChunk) -> - {ok, #delayed_resp{ + {ok, start_deadline(#delayed_resp{ start_fun = fun start_chunked_response/3, req = Req, code = Code, headers = Headers, chunks = [FirstChunk], buffer_response = buffer_response(Req) - }}. + })}. send_delayed_chunk(#delayed_resp{buffer_response = false} = DelayedResp, Chunk) -> {ok, #delayed_resp{resp = Resp} = DelayedResp1} = - start_delayed_response(DelayedResp), + start_delayed_response(cancel_deadline(DelayedResp)), {ok, Resp} = send_chunk(Resp, Chunk), {ok, DelayedResp1}; send_delayed_chunk(#delayed_resp{buffer_response = true} = DelayedResp, Chunk) -> @@ -997,6 +998,21 @@ get_delayed_req(#delayed_resp{req = #httpd{mochi_req = MochiReq}}) -> get_delayed_req(Resp) -> Resp:get(request). +start_deadline(#delayed_resp{deadline = undefined} = DelayedResp) -> + case fabric_util:request_timeout() of + infinity -> + DelayedResp; + Timeout -> + {ok, TRef} = timer:kill_after(Timeout), + DelayedResp#delayed_resp{deadline = TRef} + end. + +cancel_deadline(#delayed_resp{deadline = undefined} = DelayedResp) -> + DelayedResp; +cancel_deadline(#delayed_resp{} = DelayedResp) -> + timer:cancel(DelayedResp#delayed_resp.deadline), + DelayedResp#delayed_resp{deadline = undefined}. + start_delayed_response(#delayed_resp{resp = nil} = DelayedResp) -> #delayed_resp{ start_fun = StartFun,
