-
Notifications
You must be signed in to change notification settings - Fork 54
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
Using await in handlers appears to have a substantial performance penalty #84
Comments
I believe the issue here is that |
Yeah of course, here's what I have put together: import httpbeast, std/asyncdispatch, std/options
proc onRequest(req: Request): Future[void] {.async.} =
if req.httpMethod == some(HttpGet):
case req.path.get()
of "/":
addTimer(10, true, proc(fd: AsyncFD): bool =
req.send(Http200, "abcdefghijklmnopqrstuvwxyz")
return true
)
else:
req.send(Http404)
run(onRequest) However, when I run it and start making requests to the server I get:
I am hopefully not missing something obvious. Let me know if I've misunderstood the suggestion. Your idea that perhaps sleepAsync is the cause is worth investigating. I'm going to try setting up a dummy AsyncHttpServer server that takes 10ms to respond and |
As another experiment I just tried using the simple AsyncHttpServer I posted source for above running on port 8081 as an alternative for sleepAsync: import httpbeast, std/asyncdispatch, std/options, std/httpclient
proc onRequest(req: Request): Future[void] {.async.} =
if req.httpMethod == some(HttpGet):
case req.path.get()
of "/":
let client = newAsyncHttpClient()
discard await client.get("http://localhost:8081/")
req.send(Http200, "abcdefghijklmnopqrstuvwxyz")
else:
req.send(Http404)
run(onRequest) Then started running the wrk command, however after a bit it stops due to:
If I turn --threads:off, this error does not occur and the performance is much better than the stuck-at-100 I was seeing so I do think your sleepAsync thought is a good one. I still haven't gotten await + threads + HttpBeast working though. |
Try something like this (untested): import httpbeast, std/asyncdispatch, std/options
proc fdSleep(): Future[void] =
var res = newFuture[void]()
addTimer(10, true, proc (fd: AsyncFD): bool = res.complete(); return true)
return res
proc onRequest(req: Request): Future[void] {.async.} =
if req.httpMethod == some(HttpGet):
case req.path.get()
of "/":
await fdSleep()
req.send(Http200, "abcdefghijklmnopqrstuvwxyz")
else:
req.send(Http404)
run(onRequest) |
Ah got it, thanks! That works perfect and fully fixes the unexpected performance drop. While the sleepAsync issue remains a thing, to me that is not on the same level at all as what this appeared to be before knowing that. It seems the sleepAsync issue may be in Nim's async code not in HttpBeast? If that is the case this issue can be closed I would say and a new one for that could be opened, which is much less of an issue than this appeared to be. |
Cool. Glad to hear it works and that my guess was correct :) What does the performance look like now? The |
When using As for sleepAsync, yeah I can see the trade-offs. I'd say its not a burning issue given production code probably doesn't make much use of it, I just didn't realize it was a trap for benchmarking is all. |
Hello, I noticed some unexpected performance behavior when benchmarking HttpBeast and wanted to open an issue here in the hope of finding the cause or seeing if perhaps I'm misunderstanding something.
Here is the very simple HTTP server running on an Ubuntu 22.04 Linux server.
And the benchmarking command is
wrk -t10 -c100 -d10s http://localhost:8080
No matter how I build this server, I always end up with a result of around Requests/sec: 99.82
This includes, -d:release,danger --threads:on,off
If I comment out the
await sleepAsync(10)
which is there to simulate the request taking a little time before responding (like talking to Redis or Posgres or RPC or whatever) the performance goes way way up, Requests/sec: 375,486.11This is a pretty sizeable performance drop from using
await
, which is a normal thing to do in an async handler.This issue appears to affect HttpBest, Jester, and Prologue that I have tested.
It appears what I have noticed may be related to #20 but I've not dug into that very deeply.
One more note:
The following simple AsyncHttpServer:
Does not have this unexpected performance penalty, getting Requests/sec: 8,040.98
This result has been reproduced on two different Linux servers by two different people.
Compiler:
The text was updated successfully, but these errors were encountered: