Skip to content

Commit 5d2bf92

Browse files
authored
Ensure HTTPConnectionPool calls shutdown on active connections. (#422)
Trigger the correct method on HTTPConnectionPool.Connection to cancel the request and close the connection.
1 parent fb49c1b commit 5d2bf92

File tree

3 files changed

+55
-4
lines changed

3 files changed

+55
-4
lines changed

‎Sources/AsyncHTTPClient/ConnectionPool/HTTPConnectionPool.swift‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ final class HTTPConnectionPool{
235235
}
236236

237237
forconnectionin cleanupContext.cancel {
238-
connection.close(promise:nil)
238+
connection.shutdown()
239239
}
240240

241241
forconnectionIDin cleanupContext.connectBackoff {

‎Tests/AsyncHTTPClientTests/HTTPConnectionPoolTests+XCTest.swift‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ extension HTTPConnectionPoolTests{
3131
("testConnectionCreationIsRetriedUntilRequestIsFailed", testConnectionCreationIsRetriedUntilRequestIsFailed),
3232
("testConnectionCreationIsRetriedUntilPoolIsShutdown", testConnectionCreationIsRetriedUntilPoolIsShutdown),
3333
("testConnectionCreationIsRetriedUntilRequestIsCancelled", testConnectionCreationIsRetriedUntilRequestIsCancelled),
34+
("testConnectionShutdownIsCalledOnActiveConnections", testConnectionShutdownIsCalledOnActiveConnections),
3435
]
3536
}
3637
}

‎Tests/AsyncHTTPClientTests/HTTPConnectionPoolTests.swift‎

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ class HTTPConnectionPoolTests: XCTestCase{
294294
leteventLoop= eventLoopGroup.next()
295295
defer{XCTAssertNoThrow(try eventLoopGroup.syncShutdownGracefully())}
296296

297-
letrequest=try!HTTPClient.Request(url:"http://localhost:9000")
297+
letrequest=try!HTTPClient.Request(url:"http://localhost:\(httpBin.port)")
298298
letpoolDelegate=TestDelegate(eventLoop: eventLoop)
299299

300300
letpool=HTTPConnectionPool(
@@ -318,7 +318,7 @@ class HTTPConnectionPoolTests: XCTestCase{
318318

319319
varmaybeRequest:HTTPClient.Request?
320320
varmaybeRequestBag:RequestBag<ResponseAccumulator>?
321-
XCTAssertNoThrow(maybeRequest =tryHTTPClient.Request(url:"https://localhost:\(httpBin.port)"))
321+
XCTAssertNoThrow(maybeRequest =tryHTTPClient.Request(url:"http://localhost:\(httpBin.port)"))
322322
XCTAssertNoThrow(maybeRequestBag =tryRequestBag(
323323
request:XCTUnwrap(maybeRequest),
324324
eventLoopPreference:.indifferent,
@@ -332,13 +332,63 @@ class HTTPConnectionPoolTests: XCTestCase{
332332
guardlet requestBag = maybeRequestBag else{returnXCTFail("Expected to get a request")}
333333

334334
pool.executeRequest(requestBag)
335-
XCTAssertNoThrow(try eventLoop.scheduleTask(in:.milliseconds(100)){}.futureResult.wait())
335+
XCTAssertNoThrow(try eventLoop.scheduleTask(in:.seconds(1)){}.futureResult.wait())
336336
requestBag.cancel()
337337

338338
XCTAssertThrowsError(try requestBag.task.futureResult.wait()){
339339
XCTAssertEqual($0 as?HTTPClientError,.cancelled)
340340
}
341+
XCTAssertGreaterThanOrEqual(httpBin.createdConnections,3)
342+
}
343+
344+
func testConnectionShutdownIsCalledOnActiveConnections(){
345+
lethttpBin=HTTPBin()
346+
defer{XCTAssertNoThrow(try httpBin.shutdown())}
347+
leteventLoopGroup=MultiThreadedEventLoopGroup(numberOfThreads:1)
348+
leteventLoop= eventLoopGroup.next()
349+
defer{XCTAssertNoThrow(try eventLoopGroup.syncShutdownGracefully())}
350+
351+
letrequest=try!HTTPClient.Request(url:"http://localhost:\(httpBin.port)")
352+
letpoolDelegate=TestDelegate(eventLoop: eventLoop)
353+
354+
letpool=HTTPConnectionPool(
355+
eventLoopGroup: eventLoopGroup,
356+
sslContextCache:.init(),
357+
tlsConfiguration:.none,
358+
clientConfiguration:.init(),
359+
key:.init(request),
360+
delegate: poolDelegate,
361+
idGenerator:.init(),
362+
backgroundActivityLogger:.init(label:"test")
363+
)
364+
365+
varmaybeRequest:HTTPClient.Request?
366+
varmaybeRequestBag:RequestBag<ResponseAccumulator>?
367+
XCTAssertNoThrow(maybeRequest =tryHTTPClient.Request(url:"http://localhost:\(httpBin.port)/wait"))
368+
XCTAssertNoThrow(maybeRequestBag =tryRequestBag(
369+
request:XCTUnwrap(maybeRequest),
370+
eventLoopPreference:.indifferent,
371+
task:.init(eventLoop: eventLoopGroup.next(), logger:.init(label:"test")),
372+
redirectHandler:nil,
373+
connectionDeadline:.now()+.seconds(5),
374+
idleReadTimeout:nil,
375+
delegate:ResponseAccumulator(request:XCTUnwrap(maybeRequest))
376+
))
377+
378+
guardlet requestBag = maybeRequestBag else{returnXCTFail("Expected to get a request")}
379+
380+
pool.executeRequest(requestBag)
381+
XCTAssertNoThrow(try eventLoop.scheduleTask(in:.milliseconds(500)){}.futureResult.wait())
382+
pool.shutdown()
383+
384+
XCTAssertNoThrow(try poolDelegate.future.wait())
385+
386+
XCTAssertThrowsError(try requestBag.task.futureResult.wait()){
387+
XCTAssertEqual($0 as?HTTPClientError,.cancelled)
388+
}
389+
341390
XCTAssertGreaterThanOrEqual(httpBin.createdConnections,1)
391+
XCTAssertGreaterThanOrEqual(httpBin.activeConnections,0)
342392
}
343393
}
344394

0 commit comments

Comments
(0)