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

Add reference implementation for higher numbers of concurrent requests to HTTP1Server #172

Closed
GeorgeLyon opened this issue Mar 15, 2018 · 4 comments

Comments

@GeorgeLyon
Copy link

It is likely I'm missing something, but here we go:

Expected behavior

I should be able to get more than 6 concurrent requests from NIOHTTP1Server

Actual behavior

I'm tracking concurrent requests like so:
https://gist.github.com/GeorgeLyon/df6f34c7260997f5c373ac9a1e81c9a7

If I spam the server with requests to /write-delay, my max stays at 6. I would like that to be much higher.

It seems to me that NIO is allowing 1 active channel per core only. Do I need to do something special to "suspend" the Channel for the duration of the long running task so as to let the next request through? I didn't see anything in ChannelOptions, ServerBootstrap or ChannelHandlerContext to adjust this.

SwiftNIO version/commit hash

1fdee50

Swift & OS version (output of swift --version && uname -a)

Apple Swift version 4.1 (swiftlang-902.0.43 clang-902.0.37.1)
Target: x86_64-apple-darwin17.4.0
Darwin Georges-MacBook-Pro-2.local 17.4.0 Darwin Kernel Version 17.4.0: Sun Dec 17 09:19:54 PST 2017; root:xnu-4570.41.2~1/RELEASE_X86_64 x86_64

@helje5
Copy link
Contributor

helje5 commented Mar 15, 2018

Your "end" counter is flawed, you need to put your counter in the schedule block:

Not this:

         case .end(_):
+            queue.sync {
+                if concurrentRequests > maxConcurrentRequests {
+                    maxConcurrentRequests = concurrentRequests
+                    print(maxConcurrentRequests)
+                }
+                concurrentRequests -= 1
+            }
+            
             _ = ctx.eventLoop.scheduleTask(in: delay) { () -> Void in

but this:

         case .end(_):
             _ = ctx.eventLoop.scheduleTask(in: delay) { () -> Void in
+              queue.sync {
+                  if concurrentRequests > maxConcurrentRequests {
+                      maxConcurrentRequests = concurrentRequests
+                      print(maxConcurrentRequests)
+                  }
+                  concurrentRequests -= 1
+              }
+            

(you count before the artificial "delay")

@GeorgeLyon
Copy link
Author

GeorgeLyon commented Mar 15, 2018

Whoops, I actually did catch this but posted an incorrect gist (I have updated it). This just adds 1. to the max (before it was 5, after it becomes 6) which is consistent with my theory that a single request seems to be blocking the next request from coming in.

@helje5
Copy link
Contributor

helje5 commented Mar 15, 2018

How do you "spam the server"?

@GeorgeLyon
Copy link
Author

Ah thank you! You guessed correctly. My test environment was going between HTTP2 (for reference) and HTTP1 (for swift-nio, since it doesn't support 2 yet). Maximum number of HTTP1 connections (for my client) was 6. Increasing the maximum worked correctly.

weissi added a commit to weissi/swift-nio that referenced this issue Jun 13, 2020
Motivation:

Newer Swift compilers warn about implicitly tupling the payload of an
enum case whilst pattern matching.

Modification:

Stop using implicit tupling.

Result:

No warnings on newer Swift compilers.
weissi pushed a commit to weissi/swift-nio that referenced this issue Feb 3, 2024
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