icing / mod_h2

HTTP/2 module for Apache httpd
https://icing.github.io/mod_h2/
Apache License 2.0
256 stars 41 forks source link

Add H2BeamTimeout directive #221

Closed rpluem closed 3 years ago

rpluem commented 3 years ago

Add H2BeamTimeout directive in order to set separate beam timeouts per requests. If not set defaults to the timeout value of the virtual host.

icing commented 3 years ago

Yes, this would work. Would call it H2StreamTimeout maybe, as users are not really aware what a 'beam' is.

I do not yet understand the scenario where this helps. As long as no reads from input or writes to output happen, beam timeouts have no effect.

The example you mentioned was a slow backend system. So, mod_proxy forwards the request to it and then does a blocking read waiting for the response. There, only ProxyTimeout applies, right? When it then finally gets something, and writes to the output beam, the beam timeout starts on a block.

This stream output will time out when the client is really slow (and may other streams with higher priority come first and that takes a long time). Is this the scenario you'd like to fix?

rpluem commented 3 years ago

Yes, this would work. Would call it H2StreamTimeout maybe, as users are not really aware what a 'beam' is.

Sweet naming discussion :-). But yes, this would be fine for me.

I do not yet understand the scenario where this helps. As long as no reads from input or writes to output happen, beam timeouts have no effect.

The example you mentioned was a slow backend system. So, mod_proxy forwards the request to it and then does a blocking read waiting for the response. There, only ProxyTimeout applies, right? When it then finally gets something, and writes to the output beam, the beam timeout starts on a block.

This stream output will time out when the client is really slow (and may other streams with higher priority come first and that takes a long time). Is this the scenario you'd like to fix?

Yes. In my scenario I have a slow client, or better one with a high latency. In this case the 'one TCP connection' of HTTP/2 is a little bit a drawback as multiple TCP connections would probably have a higher throughput. I am aware of the tuning possibilities the TCP stack offers with regards to buffers here. But in my specific case this tuning is not easily possible for some reasons. Hence I want to have an additional possibility to increase the 'patience' on getting the request data back on the TCP connection without the need to increase the Timeout value.

icing commented 3 years ago

Yes, this would work. Would call it H2StreamTimeout maybe, as users are not really aware what a 'beam' is.

Sweet naming discussion :-). But yes, this would be fine for me.

;-)

Yes. In my scenario I have a slow client, or better one with a high latency. In this case the 'one TCP connection' of HTTP/2 is a little bit a drawback as multiple TCP connections would probably have a higher throughput. I am aware of the tuning possibilities the TCP stack offers with regards to buffers here. But in my specific case this tuning is not easily possible for some reasons. Hence I want to have an additional possibility to increase the 'patience' on getting the request data back on the TCP connection without the need to increase the Timeout value.

I think the correct and most simple approach here would be to have no timeouts on stream output. Imagine a client opens two streams 1 and 3. 1 has priority over 3 and is a 1GB file. stream 3 will not get 'space' on the main connection for some time. It would be tricky to set the 'correct' timeout value.

OTOH, this would give opportunities for DoS exploits. There is some protection in h2, as not all streams opened are always scheduled for processing. Maybe that could take such blocked streams better into account.

Another scenario would be a response consisting of a large file and some footer. The file bucket would get immediately pulled through the beam and the write of the footer would then hang until the file is sent on the main connection. Not a common scenario, but to illuminate that blocking on streams can be more tricky.

Hmm.

I think H2StreamTimeout can be a stop-gap until we have a good feeling about a more self-adjusting approach here (and then ignore the setting in the future).

WDYT?

icing commented 3 years ago

Commenting myself: this is nevertheless the right configuration, even if we later do not apply it to the beam directly, but consider more the overall stream timing.

rpluem commented 3 years ago

I think H2StreamTimeout can be a stop-gap until we have a good feeling about a more self-adjusting approach here (and then ignore the setting in the future).

Self-adjusting in the future sounds good, but I guess we would still need to consider the value someone set via H2StreamTimeout. But I agree that the default should change then from server Timeout to self adjusting and maybe we should a value of auto or something like this for H2StreamTimeout then to get it back to self adjusting.

BTW: Thanks for merging. Any timetable by when you want to bring icing/pipes to `trunk?

icing commented 3 years ago

BTW: Thanks for merging. Any timetable by when you want to bring icing/pipes to `trunk?

Probably next week, it runs stable in my testing for some time now and I would like to give people here more opportunity for trying it out.