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
@Body InputStream Blocks nioEventloop when its not read #6100
Comments
To reproduce run PayloadInputStreamSpec. In logs can grep on "Server received streaming message " for thread pool used. |
how is this manifesting as a problem? The event loop is indeed used to read the data but that is correct, do you have an example that demonstrates the stuck threads problem described? |
The thread where that message is printed is not the same as the tread where a block occurs waiting for the data. This seems related to the logging of the data. I commented out |
@graemerocher In our application we have readiness, liveliness enabled and multiple http client calls on every request. What we have seen is with inputstream as body request get stuck on http client call (if body is not read). If we change body to byte[] or read it from stream before making client call, it works. From thread dump in stuck thread case we can see one of the eventloop thread is TIMED_WAITING state waiting for body to be read. |
@sumitaneja If you aren't reading the body then the Netty thread will have to wait because it doesn't buffer. If you want buffering or other advanced behavior then use a reactive stream |
@jameskleeh logging was enabled for diagnostic purposes to see on which thread body was being read. |
@jameskleeh we need to invoke another library which requires inputstream. And content can be as large as 1 GB. so byte array is not an option. |
@sumitaneja please provider a reproducer. Thanks. |
From micronaut 2.5.5. documentation: Core Features |
@sumitaneja That is referring to input streams returned from controllers, however its also not the case but it once was. Thanks for letting us know. |
Updated reproducer with blocking threads, IN zip resources under test also contain thread dump. |
The test passes for me. Ran it several times |
This might have some relation with default nioeventloop size, its consistent on my box. In Spec file you can change max to 20 to increase clients. |
I can indeed reproduce with a value of 30. Thanks for the reproducer. |
So yeah the input stream is indeed blocking the event loop, I think we need to run the reading of the body data on a different thread. However there is a workaround for your use case since the root cause is that you are using blocking operations on the client. If you want to do this you should configure a different thread pool for client requests like: micronaut:
netty:
event-loops:
client-loop:
num-threads: 10 # or whatever is appropriate for your app and the load it handles
prefer-native-transport: true
http:
client:
read-timeout: 300s
event-loop-group: client-loop |
With the above change to the configuration the application behaves correctly although the input stream reading is still happening on the server event loop which may lead to contention so I think we still need to investigate that. |
* Don't block the event loop when reading inputstream. Fixes #6100 * Use only publishOn * add issue link * synchronize access to input stream * Lazily init processor * Skip offloading to IO Co-authored-by: jameskleeh <james.kleeh@gmail.com>
Expected Behavior
When using large payloads say approx 5 mb, Expected to be body read to happen on IO threadpool. Tried Both micronaut 2.5.5 and 2.5.12
application.yaml
Method Signature
Actual Behaviour
When using large payloads say approx 5 mb, body read Happen on NIO thread pool blocking the event loop. This cause stuck threads in our application.
application.yaml
Method Signature
Steps To Reproduce
No response
Environment Information
No response
Example Application
No response
Version
2.5.5, 2.5.12
The text was updated successfully, but these errors were encountered: