AsyncHttpClient: return from requests before body completion
Store the body completion future at the client and wait for it to complete before issuing additional requests. This allows the body FutureStream reader to drain the stream and read buffers to be freed asynchronously. Fix #8109
This commit is contained in:
parent
9b9cfa7306
commit
817e4bb2fe
1 changed files with 13 additions and 2 deletions
|
|
@ -807,6 +807,7 @@ type
|
||||||
lastProgressReport: float
|
lastProgressReport: float
|
||||||
when SocketType is AsyncSocket:
|
when SocketType is AsyncSocket:
|
||||||
bodyStream: FutureStream[string]
|
bodyStream: FutureStream[string]
|
||||||
|
parseBodyFut: Future[void]
|
||||||
else:
|
else:
|
||||||
bodyStream: Stream
|
bodyStream: Stream
|
||||||
getBody: bool ## When `false`, the body is never read in requestAux.
|
getBody: bool ## When `false`, the body is never read in requestAux.
|
||||||
|
|
@ -1066,10 +1067,14 @@ proc parseResponse(client: HttpClient | AsyncHttpClient,
|
||||||
if getBody:
|
if getBody:
|
||||||
when client is HttpClient:
|
when client is HttpClient:
|
||||||
client.bodyStream = newStringStream()
|
client.bodyStream = newStringStream()
|
||||||
|
result.bodyStream = client.bodyStream
|
||||||
|
parseBody(client, result.headers, result.version)
|
||||||
else:
|
else:
|
||||||
client.bodyStream = newFutureStream[string]("parseResponse")
|
client.bodyStream = newFutureStream[string]("parseResponse")
|
||||||
await parseBody(client, result.headers, result.version)
|
|
||||||
result.bodyStream = client.bodyStream
|
result.bodyStream = client.bodyStream
|
||||||
|
assert(client.parseBodyFut.isNil or client.parseBodyFut.finished)
|
||||||
|
client.parseBodyFut = parseBody(client, result.headers, result.version)
|
||||||
|
# do not wait here for the body request to complete
|
||||||
|
|
||||||
proc newConnection(client: HttpClient | AsyncHttpClient,
|
proc newConnection(client: HttpClient | AsyncHttpClient,
|
||||||
url: Uri) {.multisync.} =
|
url: Uri) {.multisync.} =
|
||||||
|
|
@ -1159,6 +1164,12 @@ proc requestAux(client: HttpClient | AsyncHttpClient, url: string,
|
||||||
# Helper that actually makes the request. Does not handle redirects.
|
# Helper that actually makes the request. Does not handle redirects.
|
||||||
let requestUrl = parseUri(url)
|
let requestUrl = parseUri(url)
|
||||||
|
|
||||||
|
when client is AsyncHttpClient:
|
||||||
|
if not client.parseBodyFut.isNil:
|
||||||
|
# let the current operation finish before making another request
|
||||||
|
await client.parseBodyFut
|
||||||
|
client.parseBodyFut = nil
|
||||||
|
|
||||||
await newConnection(client, requestUrl)
|
await newConnection(client, requestUrl)
|
||||||
|
|
||||||
let effectiveHeaders = client.headers.override(headers)
|
let effectiveHeaders = client.headers.override(headers)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue