You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
AHC seems to hold onto its body streaming delegate closure even after the request is complete. That means it's pretty much impossible to use it for bidi streaming without leaking it.
test case
func testStuff()throws{letgroup=MultiThreadedEventLoopGroup(numberOfThreads:1)defer{XCTAssertNoThrow(try group.syncShutdownGracefully())}letserver=tryServerBootstrap(group: group).childChannelInitializer{ channel in
channel.eventLoop.scheduleTask(in:.milliseconds(500)){
channel.writeAndFlush(ByteBuffer(string:"HTTP/1.1 200 ok\r\ncontent-length: 2\r\n\r\nok")).map{
channel.close(promise:nil)}.whenComplete{ result inprint("server write complete", result)}}return channel.eventLoop.makeSucceededFuture(())}.bind(host:"127.1", port:0).wait()defer{XCTAssertNoThrow(try server.close().wait())}varrequest=tryHTTPClient.Request(url:"http://\(server.localAddress!.ipAddress!):\(server.localAddress!.port!)/",
method:.POST)letwriterPromise=self.group.any().makePromise(of:HTTPClient.Body.StreamWriter.self)letdonePromise=self.group.any().makePromise(of:Void.self)classLeakDetector{init(){print("INIT")}deinit{print("DEINIT")}}varleakDetector:LeakDetector?=LeakDetector()
request.body =.stream {[leakDetector] writer in
_ = leakDetector
writerPromise.succeed(writer)return donePromise.futureResult
}
weak varweakLeak:LeakDetector?= leakDetector
leakDetector =nilletresultFuture=self.httpClient.execute(request: request)
request.body =nil // this is pointless but whatever
writerPromise.futureResult.whenSuccess{ writer in
writer.write(.byteBuffer(ByteBuffer(string:"hello"))).map{print("written")}.cascade(to: donePromise)}print("HTTP sent")letresult=try resultFuture.wait()XCTAssertEqual(.ok, result.status)XCTAssertEqual("ok", result.body.map{String(buffer: $0)}??"none")print("HTTP done", result)while weakLeak !=nil{print("not nil")sleep(1)}}
The text was updated successfully, but these errors were encountered:
weissi
changed the title
AHC holds onto its body streaming delegate even after the request is complete
AHC holds onto its body stream writer even after the request is complete
Feb 3, 2023
Presumably the easiest fix is to stop holding onto Request.body in the RequestBag type once we've started sending the body.
The retain cycle is something like RequestBag -> Request -> (if it captures a promise to be fulfilled with BodyStreamWiter) BodyStreamWriter -> RequestBag
Uh oh!
There was an error while loading. Please reload this page.
AHC seems to hold onto its body streaming delegate closure even after the request is complete. That means it's pretty much impossible to use it for bidi streaming without leaking it.
test case
The text was updated successfully, but these errors were encountered: