- Notifications
You must be signed in to change notification settings - Fork 136
Description
This test triggers a precondition failure: preconditionInEventLoop
func testRequestWithSharedEventLoopGroup()throws{lethttpBin=HttpBin()leteventLoopGroup=MultiThreadedEventLoopGroup(numberOfThreads:8)lethttpClient=HTTPClient(eventLoopGroupProvider:.shared(eventLoopGroup))defer{try! eventLoopGroup.syncShutdownGracefully() httpBin.shutdown()}letresponse=try httpClient.get(url:"http://localhost:\(httpBin.port)/events/10/1").wait()XCTAssertEqual(.ok, response.status)}Note that I am using my own EventLoopGroup to run the HTTPClient.
The problem is in execute method. In the beginning of the function, we ask the event loop group for an EventLoop and associate this event loop with the Task. But, the ChannelBootstrap will ask the event loop group again for an event loop which will likely be a different one. So in the end the Channel will actually live on a different event loop than the Task.
Then in
self.delegate.didReceivePart(task:self.task, body).whenComplete{ result inself.handleBackpressureResult(context: context, result: result)}The delegate will create a completion future from the eventLoop property of Task. So self.handleBackpressureResult will be executed on this event loop and thus context.read() will be executed on a different event loop than what the context expects -> 💥
Possible fixes
- Make sure that event loop of
Taskis the same as the one from the channel. - and/or: make sure that delegate callbacks hop back to the
EventLoopof the channel