diff --git a/Sources/AsyncHTTPClient/ConnectionPool/HTTPConnectionPool.swift b/Sources/AsyncHTTPClient/ConnectionPool/HTTPConnectionPool.swift index c9206765c..ba8c7ae62 100644 --- a/Sources/AsyncHTTPClient/ConnectionPool/HTTPConnectionPool.swift +++ b/Sources/AsyncHTTPClient/ConnectionPool/HTTPConnectionPool.swift @@ -149,12 +149,15 @@ extension HTTPConnectionPool { } var requiredEventLoop: EventLoop? { - switch self.req.eventLoopPreference.preference { - case .indifferent, .delegate: - return nil - case .delegateAndChannel(on: let eventLoop), .testOnly_exact(channelOn: let eventLoop, delegateOn: _): - return eventLoop - } + self.req.requiredEventLoop + } + + var preferredEventLoop: EventLoop { + self.req.preferredEventLoop + } + + var connectionDeadline: NIODeadline? { + self.req.connectionDeadline } func __testOnly_wrapped_request() -> HTTPSchedulableRequest { diff --git a/Sources/AsyncHTTPClient/ConnectionPool/HTTPExecutableRequest.swift b/Sources/AsyncHTTPClient/ConnectionPool/HTTPExecutableRequest.swift index c9d40eeac..1b399bb18 100644 --- a/Sources/AsyncHTTPClient/ConnectionPool/HTTPExecutableRequest.swift +++ b/Sources/AsyncHTTPClient/ConnectionPool/HTTPExecutableRequest.swift @@ -146,8 +146,12 @@ protocol HTTPSchedulableRequest: HTTPExecutableRequest { /// A connection to run this task on needs to be found before this deadline! var connectionDeadline: NIODeadline { get } - /// The task's `EventLoop` preference - var eventLoopPreference: HTTPClient.EventLoopPreference { get } + /// The user has expressed an intent for this request to be executed on this EventLoop. If a + /// connection is available on another one, just use the one handy. + var preferredEventLoop: EventLoop { get } + + /// The user required the request to be executed on a connection that is handled by this EventLoop. + var requiredEventLoop: EventLoop? { get } /// Informs the task, that it was queued for execution /// diff --git a/Sources/AsyncHTTPClient/RequestBag.swift b/Sources/AsyncHTTPClient/RequestBag.swift index eae720ca6..56d5db115 100644 --- a/Sources/AsyncHTTPClient/RequestBag.swift +++ b/Sources/AsyncHTTPClient/RequestBag.swift @@ -335,6 +335,26 @@ extension RequestBag: HTTPSchedulableRequest { } extension RequestBag: HTTPExecutableRequest { + var requiredEventLoop: EventLoop? { + switch self.eventLoopPreference.preference { + case .indifferent, .delegate: + return nil + case .delegateAndChannel(on: let eventLoop), .testOnly_exact(channelOn: let eventLoop, delegateOn: _): + return eventLoop + } + } + + var preferredEventLoop: EventLoop { + switch self.eventLoopPreference.preference { + case .indifferent: + return self.task.eventLoop + case .delegate(let eventLoop), + .delegateAndChannel(on: let eventLoop), + .testOnly_exact(channelOn: let eventLoop, delegateOn: _): + return eventLoop + } + } + func willExecuteRequest(_ executor: HTTPRequestExecutor) { if self.task.eventLoop.inEventLoop { self.willExecuteRequest0(executor) diff --git a/Tests/AsyncHTTPClientTests/HTTPConnectionPool+RequestQueueTests.swift b/Tests/AsyncHTTPClientTests/HTTPConnectionPool+RequestQueueTests.swift index 500bcf296..90bb43a2c 100644 --- a/Tests/AsyncHTTPClientTests/HTTPConnectionPool+RequestQueueTests.swift +++ b/Tests/AsyncHTTPClientTests/HTTPConnectionPool+RequestQueueTests.swift @@ -24,14 +24,14 @@ class HTTPConnectionPool_RequestQueueTests: XCTestCase { var queue = HTTPConnectionPool.RequestQueue() XCTAssertTrue(queue.isEmpty) XCTAssertEqual(queue.count, 0) - let req1 = MockScheduledRequest(eventLoopPreference: .indifferent) + let req1 = MockScheduledRequest(requiredEventLoop: nil) let req1ID = queue.push(.init(req1)) XCTAssertFalse(queue.isEmpty) XCTAssertFalse(queue.isEmpty(for: nil)) XCTAssertEqual(queue.count, 1) XCTAssertEqual(queue.count(for: nil), 1) - let req2 = MockScheduledRequest(eventLoopPreference: .indifferent) + let req2 = MockScheduledRequest(requiredEventLoop: nil) let req2ID = queue.push(.init(req2)) XCTAssertEqual(queue.count, 2) @@ -47,7 +47,7 @@ class HTTPConnectionPool_RequestQueueTests: XCTestCase { XCTAssertTrue(queue.isEmpty(for: eventLoop)) XCTAssertEqual(queue.count(for: eventLoop), 0) - let req3 = MockScheduledRequest(eventLoopPreference: .delegateAndChannel(on: eventLoop)) + let req3 = MockScheduledRequest(requiredEventLoop: eventLoop) let req3ID = queue.push(.init(req3)) XCTAssertFalse(queue.isEmpty(for: eventLoop)) XCTAssertEqual(queue.count(for: eventLoop), 1) @@ -60,13 +60,13 @@ class HTTPConnectionPool_RequestQueueTests: XCTestCase { XCTAssertTrue(queue.isEmpty) XCTAssertEqual(queue.count, 0) - let req4 = MockScheduledRequest(eventLoopPreference: .delegateAndChannel(on: eventLoop)) + let req4 = MockScheduledRequest(requiredEventLoop: eventLoop) let req4ID = queue.push(.init(req4)) XCTAssert(queue.remove(req4ID)?.__testOnly_wrapped_request() === req4) - let req5 = MockScheduledRequest(eventLoopPreference: .indifferent) + let req5 = MockScheduledRequest(requiredEventLoop: nil) queue.push(.init(req5)) - let req6 = MockScheduledRequest(eventLoopPreference: .delegateAndChannel(on: eventLoop)) + let req6 = MockScheduledRequest(requiredEventLoop: eventLoop) queue.push(.init(req6)) let all = queue.removeAll() let testSet = all.map { $0.__testOnly_wrapped_request() } @@ -82,13 +82,15 @@ class HTTPConnectionPool_RequestQueueTests: XCTestCase { } private class MockScheduledRequest: HTTPSchedulableRequest { - init(eventLoopPreference: HTTPClient.EventLoopPreference) { - self.eventLoopPreference = eventLoopPreference + let requiredEventLoop: EventLoop? + + init(requiredEventLoop: EventLoop?) { + self.requiredEventLoop = requiredEventLoop } var logger: Logger { preconditionFailure("Unimplemented") } var connectionDeadline: NIODeadline { preconditionFailure("Unimplemented") } - let eventLoopPreference: HTTPClient.EventLoopPreference + var preferredEventLoop: EventLoop { preconditionFailure("Unimplemented") } func requestWasQueued(_: HTTPRequestScheduler) { preconditionFailure("Unimplemented")