Idea #7477
open[SDKs] Go Keep client enforces a minimum transfer rate for proxy connections
Description
The gist of this story is "Make the Go Keep client have the same functionality the Python Keep client gets from #7235." Don't set any hard time limit for a block to be transferred to or from a Keep proxy. Instead, simply ensure that the connection keeps making progress, and fails if it stalls.
Implementation¶
Make a wrapper for an io.Reader that returns an error if traffic rate falls below a given rate.
The returned reader should- Be a private type (
type minProgressReader struct {...}) - Proxy each
Read()call to the underlying reader - Return an error if the underlying reader goes more than
periodseconds without returning at leastminBytesbytes - in its
Close()method, callClose()on the underlying reader if it implementsio.ReadCloser, otherwise do nothing - if given a threshold of 0 bytes or interval of 0 seconds, do not enforce any limit at all, just pass through Read() to the underlying reader.
Should be possible to implement the timer using https://golang.org/pkg/time/#NewTimer
Perhaps something like this
func NewMinProgressReader(r io.Reader, minBytes int, period time.Duration) io.ReadCloser {
return &minProgressReader{
reader: r,
minBytes: minBytes,
timer: time.NewTimer(period),
}
}
func (r *minProgressReader) Read(buf []byte) (int, error) {
if r.err != nil {
return 0, r.err
}
var n int
var err error
ok := make(chan struct{})
go func() {
n, err = r.reader.Read(buf)
ok <- struct{}{}
}()
select {
case <-ok:
r.haveBytes += n
if r.haveBytes >= r.minBytes {
r.timer.Reset()
r.haveBytes = 0
}
return n, err
case <-timer.C:
r.Close()
r.err = ErrTransferTooSlow
return n, r.err
}
}
Wrap the relevant readers in sdk/go/keepclient with NewMinProgressReader().
The caller should be able to adjust the #bytes and time interval by setting public fields on a KeepClient. MakeKeepClient() should initialize with reasonable defaults. The existing network timeout settings should be disabled: this will make them redundant.
The current (non-proxy) timeout default is 20 seconds for an entire block transfer, which would be expressed as minBytes==2<<26 && period==20*time.Second. Something more like minBytes==2<<20 && period==20*time.Second is probably reasonable for both proxy and non-proxy scenarios.
Updated by Brett Smith over 10 years ago
- Target version set to Arvados Future Sprints
Updated by Ward Vandewege over 4 years ago
- Target version deleted (
Arvados Future Sprints)