agent/dockerclient/dockerapi/inactivity_timeout_handler.go
func handleInactivityTimeout(reader io.ReadCloser, timeout time.Duration, cancelRequest func(), canceled *uint32) (io.ReadCloser, chan<- struct{}) {
	done := make(chan struct{})
	proxyReader := &proxyReader{ReadCloser: reader}
	go func() {
		var lastCallCount uint64
		for {
			select {
			case <-time.After(timeout):
			case <-done:
				return
			}
			curCallCount := proxyReader.callCount()
			if curCallCount == lastCallCount {
				atomic.AddUint32(canceled, 1)
				cancelRequest()
				return
			}
			lastCallCount = curCallCount
		}
	}()
	return proxyReader, done
}
func handleInactivityTimeout(reader io.ReadCloser, timeout time.Duration, cancelRequest func(), canceled *uint32) (io.ReadCloser, chan<- struct{}) {
	done := make(chan struct{})
	proxyReader := &proxyReader{ReadCloser: reader}
	go func() {
		var lastCallCount uint64
		for {
			select {
			case <-time.After(timeout):
			case <-done:
				return
			}
			curCallCount := proxyReader.callCount()
			if curCallCount == lastCallCount {
				atomic.AddUint32(canceled, 1)
				cancelRequest()
				return
			}
			lastCallCount = curCallCount
		}
	}()
	return proxyReader, done
}
// When pulling an image, the docker api will pull and then subsequently unzip the downloaded artifacts. Docker does
// not separate the "pull" from the "unpack" step. What this means is that this timeout doesn't 'tick' while unpacking
// the downloaded files. This only causes noticeable impact with large files, but we should investigate improving this.