Correctly close files when uploading them. #174
Closed
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
When uploading files to outpack, orderly was consistently leaking file handles. While these handles would eventually be garbage collected and closed, the GC would print a lot of noise onto the console:
This seems to be like an httr/httr2 bug (the behaviour was present both before and after the upgrade), but I cannot find much reference to this issue online. There's a brief mention of it in the httr2 source, saying it "leaks connection if [the] request doesn't complete", however I am seeing this behaviour even for succesful requests.
The httr2 implementation does not make much sense to me actually: it only closes the connections on short reads, but as far as I can tell libcurl always provides an accurate
nbytes
argument to the callback, meaning short reads never actually occur.This works around that issue by not using httr2's implementation of file upload, and instead implements an alternative where the caller provides and already opened connection. It is the caller's responsibility to close it after the request is complete. The only place we use this,
orderly_location_http$put_file
, does so using awithr::defer
call to ensure this happens across all flow paths, even errors.I don't think we can easily write tests for this, since the garbage collector closes the handles for us already. The GC warnings don't get detected by
evaluate_promise
orexpect_silent
.