feross/webtorrent — pull request #190 by astro (2014-11-27 00:27:16+00:00)
Title: dynamic requests pipeline length

With the fixed `MAX_OUTSTANDING_REQUESTS` we're running into the following problems when peer communication suffers from delay:
* High-bandwidth connections become stop'n'go because there are no queued requests while the previous requests' data is still in-flight.
* Low-bandwidth peers will have requests queued that will arrive much in the future, affording for the intelligent piece selection that is approached in `Torrent.prototype._updateWire()`. Unfortunately, this mechanism is difficult to understand, lacks documentation, and has multiple TODOs. I was observing quite a delay when seeking during streaming playback.

I propose using a pipeline length based on a bandwidth-delay-product. Because we cannot measure delay properly in pipelined TCP communication, we assume a constant of half a second. Large enough to avoid jitter on TCP packet loss for most links, small enough to retain agility when reselecting (seeking in streams). There's a lower limit (`PIPELINE_MIN_DURATION`) and an upper limit (`PIPELINE_MAX_DURATION`) to send requests in batches, thereby making use of the Nagle algorithm.

By confining the pipeline length in a time-based way I think you could throw away a lot of calculation in `speedRanker()`. Of course there's a downside with high-latency links, but it will still work with the minimum of 2 in-flight requests.

The terminology is arbitrary, feel free to rename `getPipelineLength()` to something else.