Closed tomrosling closed 4 years ago
I will have a look, but please pull latest version. Those function names are old
Your explanation makes perfect sense, you're almost certainly correct. Will see how this can be solved in easiest way
Great, thanks!
If this already is 0, the following logic fails. It should always call drainHandler if backpressure already was 0:
Fixed on master, please have a test and reopen if issue persist.
Thanks
Appears to be fixed, thanks again for the quick turnaround.
Hi @tomrosling
Can you give a tutorial for .drain
handler or a example?
I cannot find anything useful for .drain
in uWebSockets/examples
.
Thank you!
Hey,
There's some documentation here: https://github.com/uNetworking/uWebSockets/blob/master/misc/READMORE.md#backpressure-in-websockets
I've changed jobs since raising this issue so no longer have access to the source code I was working with, but from what I recall/can see now, you shouldn't try to send more data than the socket can have buffered. The drain handler is called when space becomes available in the socket's send buffer. So, if you have more packets that need to be sent, you should buffer them in your application layer and send them when .drain is called.
@tomrosling
Thank you for your quick reply.
So you mean:
If I have a chunk of streaming data, I should buffer the data, send the data in .drain
handler.
But where to buffer my streaming data? When is .drain
called or in which situation .drain
will be called?
If I misunderstand your idea, please let me know.
Thank you!
You will have to manage buffering it yourself, somewhere in your application.
.drain is called when the socket is able to buffer (internally) more of your data, and you can try sending it again. As far as I recall, it will only be called if you previously tried to send something and failed due to backpressure.
Hi @tomrosling
I got your idea almostly.
If my data which need to be sent is small, .drain
will not be called in most time, right?
If .drain
is called due to backpressure, the operation under .drain
is only sending the buffer again, right?
Thank you!
Right, if you don't send much data then there will rarely be backpressure, depending on your network connection.
Yes, if you want to send more data then you should wait until drain has been called to do so. I recommend that you try it and see.
Hi,
It seems that the .drain handler isn't always called when a socket becomes writable again. What I think is happening is that send() is being called, and sending all of the remaining backpressure, after the socket has actually become writable but before the us_new_socket_context_on_writable callback has been called - so when that callback is actually called, the backpressure is already zero and my drainHandler never gets called. There are places where send() is called internally (particularly, during uncork() in the us_new_socket_context_on_data callback), which are causing this for me.
Since I'm checking ws->getBufferedAmount() before actually sending anything, and waiting for the .drain handler if it returned non-zero so I can try again, my app can get into a state where there are packets to send but it doesn't know the socket is ready to take them.
I'm working around it for now by checking if I can send my queued packets after receiving data, but it doesn't seem ideal.