-
Notifications
You must be signed in to change notification settings - Fork 221
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
Buffer writes before writing to the underlying stream #358
Conversation
b32f876
to
f1ceec0
Compare
I can probably make a similar micro-bench to show the benefits, or update the current one to include a small simulated |
Add write_buffer_size Set default 128 KiB
Fix internal method naming
629bb84
to
dea67d6
Compare
Yep, I re-calibrated the simulated io so underlying The PR 128 KiB buffer minimises underlying
|
aadc909
to
f6a610f
Compare
@agalakhov wdyt? |
We used to buffer messages and now we're effectively switching to buffering raw data instead. This seems to be a good idea. My only concern is: what happens if some data get buffered without actually sending them and then a Ping is received? How do we deal with this ordering? |
Basically the same as before, since we still auto flush when we schedule a pong response. So on the next read/write/flush if there is any This optimisation is a particularly good fit since we already did write all message frames into the |
Just for clarity; from when I started looking at the code we didn't actually buffer messages in this way, though it kind of looked like we did. They were always immediately written to the underlying stream. The old message queue would only build up on flush errors, since flush used to be called before each write attempt. That's why I removed the send_queue in #357. Messages can build up in the |
Thank you! |
Add ability to buffer multiple writes before writing to the underlying stream, controlled by
WebSocketConfig::write_buffer_size
(default 128 KiB). Improves batch message write performance.This PR comes out of some further investigation this morning regarding writing many small messages. After #357 we no longer flush on each write which gives a big boost. I wondered what would happen if we also avoided/minimised
write
calls to the underlying stream and allowed the messages to buffer in the out_buffer/write buffer.In short it does seem to provide a boost, though not as dramatic as the flush rework. With #357 my load-generator could write ~2.15M msg/s, with 128KiB write_buffer_size this goes up to ~2.44M msg/s.
Larger sizes didn't yield a benefit for me so 128KiB seems a decent default value, I'm proposing that here. The previous code essentially acted as if this value was zero, which could also be a reasonable default though users would need to opt in to get this benefit.
Note: This will only affect users that are calling
write
multiple times thenflush
. Since onflush
all write buffer data will be written regardless of this config.Naming
There is a slight issue with naming clarity here
write_buffer_size
vsmax_write_buffer_size
. I've tried to clarify as much as possible in docs. Perhaps this can be improved?