Skip to content

Commit 7311c0e

Browse files
authored
Add a request waiter box for the connection pool (#397)
1 parent ed44283 commit 7311c0e

File tree

4 files changed

+153
-0
lines changed

4 files changed

+153
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the AsyncHTTPClient open source project
4+
//
5+
// Copyright (c) 2021 Apple Inc. and the AsyncHTTPClient project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of AsyncHTTPClient project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
import NIO
16+
17+
extension HTTPConnectionPool {
18+
struct RequestID: Hashable {
19+
private let objectIdentifier: ObjectIdentifier
20+
21+
init(_ request: HTTPScheduledRequest) {
22+
self.objectIdentifier = ObjectIdentifier(request)
23+
}
24+
}
25+
26+
struct Waiter {
27+
var requestID: RequestID {
28+
RequestID(self.request)
29+
}
30+
31+
var request: HTTPScheduledRequest
32+
33+
private var eventLoopRequirement: EventLoop? {
34+
switch self.request.eventLoopPreference.preference {
35+
case .delegateAndChannel(on: let eventLoop),
36+
.testOnly_exact(channelOn: let eventLoop, delegateOn: _):
37+
return eventLoop
38+
case .delegate(on: _),
39+
.indifferent:
40+
return nil
41+
}
42+
}
43+
44+
init(request: HTTPScheduledRequest) {
45+
self.request = request
46+
}
47+
48+
func canBeRun(on option: EventLoop) -> Bool {
49+
guard let requirement = self.eventLoopRequirement else {
50+
// if no requirement exists we can run on any EventLoop
51+
return true
52+
}
53+
54+
return requirement === option
55+
}
56+
}
57+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the AsyncHTTPClient open source project
4+
//
5+
// Copyright (c) 2018-2019 Apple Inc. and the AsyncHTTPClient project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of AsyncHTTPClient project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
//
15+
// HTTPConnectionPool+WaiterTests+XCTest.swift
16+
//
17+
import XCTest
18+
19+
///
20+
/// NOTE: This file was generated by generate_linux_tests.rb
21+
///
22+
/// Do NOT edit this file directly as it will be regenerated automatically when needed.
23+
///
24+
25+
extension HTTPConnectionPool_WaiterTests {
26+
static var allTests: [(String, (HTTPConnectionPool_WaiterTests) -> () throws -> Void)] {
27+
return [
28+
("testCanBeRunIfEventLoopIsSpecified", testCanBeRunIfEventLoopIsSpecified),
29+
("testCanBeRunIfNoEventLoopIsSpecified", testCanBeRunIfNoEventLoopIsSpecified),
30+
]
31+
}
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the AsyncHTTPClient open source project
4+
//
5+
// Copyright (c) 2021 Apple Inc. and the AsyncHTTPClient project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of AsyncHTTPClient project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
@testable import AsyncHTTPClient
16+
import Logging
17+
import NIO
18+
import XCTest
19+
20+
class HTTPConnectionPool_WaiterTests: XCTestCase {
21+
func testCanBeRunIfEventLoopIsSpecified() {
22+
let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 2)
23+
24+
let theRightEL = eventLoopGroup.next()
25+
let theFalseEL = eventLoopGroup.next()
26+
27+
let mockRequest = MockScheduledRequest(eventLoopPreference: .init(.testOnly_exact(channelOn: theRightEL, delegateOn: theFalseEL)))
28+
29+
let waiter = HTTPConnectionPool.Waiter(request: mockRequest)
30+
31+
XCTAssertTrue(waiter.canBeRun(on: theRightEL))
32+
XCTAssertFalse(waiter.canBeRun(on: theFalseEL))
33+
}
34+
35+
func testCanBeRunIfNoEventLoopIsSpecified() {
36+
let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 2)
37+
38+
let mockRequest = MockScheduledRequest(eventLoopPreference: .indifferent)
39+
let waiter = HTTPConnectionPool.Waiter(request: mockRequest)
40+
41+
for el in eventLoopGroup.makeIterator() {
42+
XCTAssertTrue(waiter.canBeRun(on: el))
43+
}
44+
}
45+
}
46+
47+
private class MockScheduledRequest: HTTPScheduledRequest {
48+
init(eventLoopPreference: HTTPClient.EventLoopPreference) {
49+
self.eventLoopPreference = eventLoopPreference
50+
}
51+
52+
var logger: Logger { preconditionFailure("Unimplemented") }
53+
var connectionDeadline: NIODeadline { preconditionFailure("Unimplemented") }
54+
let eventLoopPreference: HTTPClient.EventLoopPreference
55+
56+
func requestWasQueued(_: HTTPRequestScheduler) {
57+
preconditionFailure("Unimplemented")
58+
}
59+
60+
func fail(_: Error) {
61+
preconditionFailure("Unimplemented")
62+
}
63+
}

Diff for: Tests/LinuxMain.swift

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import XCTest
3636
testCase(HTTPClientSOCKSTests.allTests),
3737
testCase(HTTPClientTests.allTests),
3838
testCase(HTTPConnectionPool_FactoryTests.allTests),
39+
testCase(HTTPConnectionPool_WaiterTests.allTests),
3940
testCase(HTTPRequestStateMachineTests.allTests),
4041
testCase(LRUCacheTests.allTests),
4142
testCase(RequestBagTests.allTests),

0 commit comments

Comments
 (0)