@@ -673,6 +673,66 @@ class HTTPClientTests: XCTestCase {
673
673
}
674
674
}
675
675
676
+ func testMultipleConcurrentRequests( ) throws {
677
+ let numberOfRequestsPerThread = 100
678
+ let numberOfParallelWorkers = 5
679
+
680
+ final class HTTPServer : ChannelInboundHandler {
681
+ typealias InboundIn = HTTPServerRequestPart
682
+ typealias OutboundOut = HTTPServerResponsePart
683
+
684
+ func channelRead( context: ChannelHandlerContext , data: NIOAny ) {
685
+ if case . end = self . unwrapInboundIn ( data) {
686
+ let responseHead = HTTPServerResponsePart . head ( . init( version: . init( major: 1 , minor: 1 ) ,
687
+ status: . ok) )
688
+ context. write ( self . wrapOutboundOut ( responseHead) , promise: nil )
689
+ context. writeAndFlush ( self . wrapOutboundOut ( . end( nil ) ) , promise: nil )
690
+ }
691
+ }
692
+ }
693
+
694
+ let group = MultiThreadedEventLoopGroup ( numberOfThreads: 2 )
695
+ defer {
696
+ XCTAssertNoThrow ( try group. syncShutdownGracefully ( ) )
697
+ }
698
+
699
+ var server : Channel ?
700
+ XCTAssertNoThrow ( server = try ServerBootstrap ( group: group)
701
+ . serverChannelOption ( ChannelOptions . socket ( . init( SOL_SOCKET) , . init( SO_REUSEADDR) ) , value: 1 )
702
+ . serverChannelOption ( ChannelOptions . backlog, value: . init( numberOfParallelWorkers) )
703
+ . childChannelInitializer { channel in
704
+ channel. pipeline. configureHTTPServerPipeline ( withPipeliningAssistance: false ,
705
+ withServerUpgrade: nil ,
706
+ withErrorHandling: false ) . flatMap {
707
+ channel. pipeline. addHandler ( HTTPServer ( ) )
708
+ }
709
+ }
710
+ . bind ( to: . init( ipAddress: " 127.0.0.1 " , port: 0 ) )
711
+ . wait ( ) )
712
+ defer {
713
+ XCTAssertNoThrow ( try server? . close ( ) . wait ( ) )
714
+ }
715
+
716
+ let httpClient = HTTPClient ( eventLoopGroupProvider: . shared( group) )
717
+ defer {
718
+ XCTAssertNoThrow ( try httpClient. syncShutdown ( ) )
719
+ }
720
+
721
+ let g = DispatchGroup ( )
722
+ for workerID in 0 ..< numberOfParallelWorkers {
723
+ DispatchQueue ( label: " \( #file) : \( #line) :worker- \( workerID) " ) . async ( group: g) {
724
+ func makeRequest( ) {
725
+ let url = " http://127.0.0.1: \( server? . localAddress? . port ?? - 1 ) /hello "
726
+ XCTAssertNoThrow ( try httpClient. get ( url: url) . wait ( ) )
727
+ }
728
+ for _ in 0 ..< numberOfRequestsPerThread {
729
+ makeRequest ( )
730
+ }
731
+ }
732
+ }
733
+ g. wait ( )
734
+ }
735
+
676
736
func testWorksWith500Error( ) {
677
737
let web = NIOHTTP1TestServer ( group: self . group)
678
738
defer {
0 commit comments