Danger
Never make blocking calls directly on an event loop.
An example of a blocking call would be something like libc.sleep(_:).
router.get("hello") { req in
/// Puts the event loop's thread to sleep.
sleep(5)
/// Returns a simple string once the thread re-awakens.
return "Hello, world!"
}
Make sure to run any blocking work in the background. Use promises to notify the event loop when this work is done in a non-blocking way.
router.get("hello") { req in
/// Create a new void promise
let promise = req.eventLoop.newPromise(Void.self)
/// Dispatch some work to happen on a background thread
DispatchQueue.global() {
/// Puts the background thread to sleep
/// This will not affect any of the event loops
sleep(5)
/// When the "blocking work" has completed,
/// complete the promise and its associated future.
promise.succeed()
}
/// Wait for the future to be completed,
/// then transform the result to a simple String
return promise.futureResult.transform(to: "Hello, world!")
}
Info
If doing blocking work is a central part of your application, you should consider using a BlockingIOThreadPool to control the number of threads you create to do blocking work. This will help you avoid starving your event loops from CPU time while blocking work is being done.
网友评论