multi: fix queueing of pending easy handles #1358
Multi handles "try and maintain a FIFO queue so the pipelined requests are in order". That is why newly added easy handles are added to end of the multi->easyp linked list.
It turns out that the requests are finished in this order:
This is caused by the repeated inversion of the list of easy handles waiting for connections (multi->pending) in a multistep process.
This particular problem could probably be solved by a quick-and-dirty solution: iterating on the multi->pending list in a reverse order in Curl_multi_process_pending_handles, negating the effect of the described process.
I would argue, however, that this problem is inherent to the workings of Curl_splaygetbest and the definition of "best" in the context of expired timeouts.
The patch that I propose contains the following modifications:
Thank you for your contribution!
You're suggesting changes to a core part of libcurl that basically has been stable and untouched for almost a decade. I think we must add some test cases for this that make sure the added functionality works as intended.
But first maybe we should discuss whether this change is really worth it. Is there any documentation anywhere that would suggest that libcurl will really try the added handles in a FIFO order? I always stress to users that libcurl does not maintain any order among the transfers an in the case where there are N transfers waiting, we have not promised a queue order to the user. I'm a little concerned that adding such a promise to docs and to users will imply that we need to work harder to maintain that, to very little gain I think. I gather you have a particular use case where FIFO order is desired?
On the issue of testing the new behaviour: you're completely right and I'd be happy to add these test cases.
The particular use case is the streaming download of a large file using multiple HTTP range requests on multiple connections (there must be multiple connections to achieve maximum throughput, but it is not feasible to use as many connections as the number of chunks in the file). It doesn't really matter in what particular order the transfers are finished, but it does matter that the chunks are downloaded in a relative order, meaning that the pending requests should be scheduled in the order of their addition. Otherwise a large buffer needs to be maintained and work on the file stream is blocked while chunks from the end of the file are being downloaded that could not be processed anyway until we've processed the previous chunks.
It is completely understandable, that no order among the transfers can and should be guaranteed, but I do think that it is the intuitive behaviour to schedule pending transfers in the order they were added and it would be a great improvement to curl.