-
Notifications
You must be signed in to change notification settings - Fork 27
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
Balance received message handling between connections #99
Comments
The exact finishing condition here is open to debate. It may, for example make sense to also limit the number of messages handled (across all connections) per epoll cycle, so as to not overwhelm other epoll clients. |
This will require some means of performing an action after all epoll clients have been handled, before the next call to Another way would be to rely on an event fd which is triggered every epoll cycle. It wouldn't be guaranteed to be handled at the end of the cycle, but simply processing pending connection messages once per cycle should be sufficient. |
Small disadvantage of using always-ready |
Why doubling? One event fd for the whole system, not one per connection. |
Ah, it wouldn't actually double it, yes, I was just going to write that. |
The processing time is not the only problem. Without a way of suspending the read loop fiber while iterating over hundreds of received messages a client application can be flooded with received messages without a chance of processing them or throttling the input stream.
Many client applications need an event loop cycle to process received records, for example because they schedule a task to send another record. But because the next event loop cycle is going to happen only after all of the hundreds of received messages have been delivered to the request handler, a high amount of scheduled tasks or outgoing messages can stack up in the application. It can be that many that they exhaust resources such as the capacity of task or message queues. |
Right, this ties into what I wrote above:
If we implement this at some point, we'll need to experiment with different approaches to see what works best. |
I wonder if this is necessary any more. The idea originated in our troubles with stream requests. These have now been (/ are being) re-implemented as batch requests. @david-eckardt-sociomantic @nemanja-boric-sociomantic what do you think? |
The current connection (read) handling works as follows:
epoll_wait
reports that one or more connections have received something.a. Check if at least one full message has been received. If not, re-register with epoll.
b. If one or more full messages have been received, iterate over them, passing them to the appropriate request handlers.
The problem is at 3b. Given the various input buffers that are in use, it's possible for hundreds (even thousands -- in experiments we have seen this) of messages on a connection to have been received and now be ready for handling. So, step 3b could actually take quite some time to handle, leaving other connections and requests starved in the meantime.
This is not ideal asynchronous behaviour -- the assumption is that handling an event is quick, allowing other epoll clients to get their share of attention.
One idea to fix this problem would be to do the following:
epoll_wait
reports that one or more connections have received something.a. Check if at least one full message has been received. If not, re-register with epoll.
b. If one or more full messages have been received, set a flag indicating that they are waiting to be handled.
The text was updated successfully, but these errors were encountered: