Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Server gets stuck on stop #19

Open
tranquvis opened this issue Jul 13, 2017 · 1 comment
Open

Server gets stuck on stop #19

tranquvis opened this issue Jul 13, 2017 · 1 comment

Comments

@tranquvis
Copy link

I have the following test in my XCTestCase, which should demonstrate the problem.

let mockServer = MockServer()
mockServer.start()

mockServer.router["/test"] = JSONResponse() { _ -> NSDictionary in
    print("request received")
    return [:]
}

print("Send request")
URLSession(configuration: URLSessionConfiguration.default)
    .dataTask(with: URL(string: "http://localhost:8080/test")!)
    .resume()

sleep(3) // Any action or tear down delay.
print("stop mock server")
mockServer.stop() // Never ends
print("mock server stopped")

MockServer is a wrapper I have made, which handles starting and stopping the server.
I followed your gist about running the server.

class MockServer {
    let router = Router()
    private let server: HTTPServer
    private let serverDispatchQueue = DispatchQueue(label: "com.timr.uitest.serverDispatchQueue", qos: .background)
    private let eventLoop: EventLoop
    private var eventLoopThreadCondition = NSCondition()
    
    init() {
        eventLoop = try! SelectorEventLoop(selector: try! KqueueSelector())
        server = DefaultHTTPServer(
            eventLoop: eventLoop,
            port: 8080,
            app: router.app
        )
    }
    
    func start() {
        try! server.start()
        eventLoopThreadCondition = NSCondition()
        serverDispatchQueue.async() {
            self.eventLoop.runForever()
            self.eventLoopThreadCondition.lock()
            self.eventLoopThreadCondition.signal()
            self.eventLoopThreadCondition.unlock()
        }
    }
    
    func stop() {
        server.stopAndWait()
        eventLoopThreadCondition.lock()
        eventLoop.stop()
        let stopEventLoopTimeout = 10.0
        while eventLoop.running {
            if !eventLoopThreadCondition.wait(until: Date(timeIntervalSinceNow: stopEventLoopTimeout)) {
                fatalError("Join eventLoopThread timeout")
            }
        }
    }
}

The problem is that the test never ends because it gets stuck at server.stopAndWait().
I get this output:

Send request
request received
stop mock server

As I digged a bit deeper I found out that the last event loop round does not finish. So the action awaited in stopAndWait, which is passed to eventLoop.call never gets called.
runOncein EventLoop gets stuck at events = try selector.select(timeout: timeout).

Would be great if you could take a look on this issue @fangpenlin. This problem is a bit too deep for me.

@patricks
Copy link

Hi, I had the same problem. You have to disable the swift compiler optimization. see envoy/Embassy#31

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants