vapor
vapor copied to clipboard
Clarify what's the best way to shutdown a Vapor server from a route handler
Is your feature request related to a problem? Please describe.
Calling shutdown()
on an Application
instance from a route handler or a WebSocket handler leads to this assertion:
Precondition failed: BUG DETECTED: wait() must not be called when on an EventLoop.
Calling wait() on any EventLoop can lead to
- deadlocks
- stalling processing of other connections (Channels) that are handled on the EventLoop that wait was called on
Further information:
- current eventLoop: Optional(SelectableEventLoop { selector = Selector { descriptor = 16 }, thread = NIOThread(name = NIO-ELT-0-#7), scheduledTasks = PriorityQueue(count: 1): [ScheduledTask(readyTime: 79776511569019)] })
- event loop associated to future: SelectableEventLoop { selector = Selector { descriptor = 6 }, thread = NIOThread(name = NIO-ELT-0-#3) }: file /Users/maxd/Documents/carton/.build/checkouts/vapor/Sources/Vapor/HTTP/Server/HTTPServer.swift, line 282
Describe the solution you'd like Provide a documented way to trigger server shutdown from a route handler or a WebSocket handler.
Describe alternatives you've considered
kill(getpid(), SIGINT)
works, but seems to be quite hacky.
Additional context This is needed to implement https://github.com/swiftwasm/carton/pull/173 cleanly. We have a build tool for SwiftWasm that fetches the Wasm binary from a Vapor server, runs it, then connects via WebSocket and to report results of the run. The server should then shutdown when notified via a WebSocket handler.
How about using this?
app.get("pleaseShutdown") { (request: Request) -> String in
let app = request.application
DispatchQueue.global().asyncAfter(deadline: .now() + 2) {
app.running?.stop()
}
return "Shutdown initiated."
}
.now() + 2
seems arbitrary here? Also, why global queue? Application
is a class instance, which is not thread-safe I guess?
I pretty much looked at ServeCommand.swift
and mirrored what happens when I press ctrl-c in the command line.
2 seconds is arbitrary.
I'm just using it for development purposes and it works fine for me. Triggered within Xcode by a Keyboard Maestro shortcut.
+1 for clarifying what the recommended way would be 😃
Using terminal:
lsof -i:[PORT_NUMBER]
sudo kill -9 [PORT_NUMBER]
In an iOS app, app.shutdown()
works.
But my question is how to restart it?
@trevor-sonic once you've shut down the app, you essentially have a fresh Application
you can start in the same way as you originally started it