Skip to content

EventLoop of Task and channel might not match #54

Closed
@t089

Description

@t089

This test triggers a precondition failure: preconditionInEventLoop

func testRequestWithSharedEventLoopGroup() throws {
    let httpBin = HttpBin()
    let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 8)
    let httpClient = HTTPClient(eventLoopGroupProvider: .shared(eventLoopGroup))
    defer {
        try! eventLoopGroup.syncShutdownGracefully()
        httpBin.shutdown()
    }
    
    let response = 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 in
                    self.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 Task is the same as the one from the channel.
  • and/or: make sure that delegate callbacks hop back to the EventLoop of the channel

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind/bugFeature doesn't work as expected.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions