@@ -1079,6 +1079,52 @@ class HTTPClientTests: XCTestCase {
1079
1079
XCTAssertNoThrow ( try EventLoopFuture < HTTPClient . Response > . andAllComplete ( futureResults, on: eventLoop) . timeout ( after: . seconds( 10 ) ) . wait ( ) )
1080
1080
}
1081
1081
1082
+ func testManyConcurrentRequestsWork( ) {
1083
+ let numberOfWorkers = 20
1084
+ let numberOfRequestsPerWorkers = 20
1085
+ let allWorkersReady = DispatchSemaphore ( value: 0 )
1086
+ let allWorkersGo = DispatchSemaphore ( value: 0 )
1087
+ let allDone = DispatchGroup ( )
1088
+
1089
+ let httpBin = HTTPBin ( )
1090
+ defer {
1091
+ XCTAssertNoThrow ( try httpBin. shutdown ( ) )
1092
+ }
1093
+ let httpClient = HTTPClient ( eventLoopGroupProvider: . createNew)
1094
+ defer {
1095
+ XCTAssertNoThrow ( try httpClient. syncShutdown ( ) )
1096
+ }
1097
+
1098
+ let url = " http://localhost: \( httpBin. port) /get "
1099
+ XCTAssertNoThrow ( XCTAssertEqual ( . ok, try httpClient. get ( url: url) . wait ( ) . status) )
1100
+
1101
+ for w in 0 ..< numberOfWorkers {
1102
+ let q = DispatchQueue ( label: " worker \( w) " )
1103
+ q. async ( group: allDone) {
1104
+ func go( ) {
1105
+ allWorkersReady. signal ( ) // tell the driver we're ready
1106
+ allWorkersGo. wait ( ) // wait for the driver to let us go
1107
+
1108
+ for _ in 0 ..< numberOfRequestsPerWorkers {
1109
+ XCTAssertNoThrow ( XCTAssertEqual ( . ok, try httpClient. get ( url: url) . wait ( ) . status) )
1110
+ }
1111
+ }
1112
+ go ( )
1113
+ }
1114
+ }
1115
+
1116
+ for _ in 0 ..< numberOfWorkers {
1117
+ allWorkersReady. wait ( )
1118
+ }
1119
+ // now all workers should be waiting for the go signal
1120
+
1121
+ for _ in 0 ..< numberOfWorkers {
1122
+ allWorkersGo. signal ( )
1123
+ }
1124
+ // all workers should be running, let's wait for them to finish
1125
+ allDone. wait ( )
1126
+ }
1127
+
1082
1128
func testRepeatedRequestsWorkWhenServerAlwaysCloses( ) {
1083
1129
let web = NIOHTTP1TestServer ( group: self . group)
1084
1130
defer {
0 commit comments