Closed fd0 closed 7 years ago
As discussed on Slack, these two commits resolve all instances of non-drained HTTP response bodies, I'm not seeing any aborted connections any more.
Hm, feels like a flaky test. Anything else I can do?
I gave the test a kick to see if it runs through OK and it did.
As for the logic - I'm a bit uneasy about replacing all the checkClose
calls.
In particular the one in ObjectGet
- callers are quite entitled to read the object for a bit then close it (rclone does exactly this when seeking objects in its fuse FS). Having checkClose
read the entire buffer here of a 5GB file would be unwise.
My suggestion would be to leave checkClose
alone and make a new drainCheckClose
then we can closely audit where those drainCheckClose
get used.
Sorry it is the one in func (file *ObjectOpenFile) Close
that we should be worrying about
sounds good, I'll rework it
If I may chime in, I share @ncw worries on this and I think a similar situation can happen with the call to checkClose
in (*Connection).ObjectGet
. Suppose I have a code for a external timeout that looks something like this:
done := make(chan bool)
go func() {
defer close(done)
conn.ObjectGet("c", "o", otherConn, false, nil)
}()
select {
case <-time.After(time.Minute):
otherConn.Close()
case <-done:
}
It's not ideal, but certainly possible, and I would expect that after closing the writer no further data would be read from this object as the io.Copy
would eventually fail. I think it would be better to drop this connection than potentially keep reading lots of data from a slow connection.
Uh, that is an excellent point, thanks for bringing it up! Any idea on what to do now?
I think the same thing @ncw suggested would be fine, keepcheckClose
as is and create a new func drainCheckClose
. This new func would replace checkClose
almost everywhere with the exception of (*ObjectOpenFile).Close
and (*Connection).ObjectGet
.
Done, let me know what you think :)
Hm, the flaky test again...
So, anything else I can do here?
Thank you @fd0 !
This allows reusing the same connection for future requests. A connection is aborted when the body is closed before reading it completely.