nitely / nim-hyperx

Pure Nim http2 client and server 🖖
MIT License
29 stars 0 forks source link

Allow changing flow-control window #6

Closed nitely closed 5 months ago

nitely commented 7 months ago

Right now we set the window to max size (2GB), and send a window update every 1GB (1, 2). Which effectively disables flow-control. Prior to this the window was set to default size, and I was sending a window update for every consumed data frame, which caused a 10x slow down on a big file data transfer.

We should provide a way to set the window size, and add some heuristic that will send window updates only when needed (maybe sending an update every half window size is consumed is fine)

nitely commented 6 months ago

There is no way for the client/server to be overwhelmed by a peer sending data faster than it can be processed because of built-in backpressure. However, not calling recv on a stream promptly will cause it to block all other streams for that connection/socket.

So flow-control is important when dealing with streams of data that won't fit in memory. We cannot keep receiving and keeping all data in memory while it's being processed.

A common use case is receiving a stream of data, transforming the data, and sending it either back or to some other endpoint. If we receive faster than we send the data needs to be kept in memory temporarily. There is no way around it, even storing it on disk could have the same issue where it's slower to write to disk than receiving the data for whatever reason (for example network disks), and either way it's a poor solution to the issue. The right solution is setting a sensible flow-control window so no more than "window size" bytes are kept in memory at a time.

Also, we currently offer no way to control the flow-control. Window updates are sent as soon as data is received. This defeats the purpose of flow-control. The window updates need to be send once the data is effectively processed and released from memory.

In short, flow-control is needed, so a stream that receives data faster than it can process it won't block other streams.

nitely commented 6 months ago

Possible solutions: