(lom *cluster.LOM)
| 157 | } |
| 158 | |
| 159 | func (t *singleObjectTask) downloadLocal(lom *cluster.LOM) (err error) { |
| 160 | var ( |
| 161 | timeout = t.initialTimeout() |
| 162 | fatal bool |
| 163 | ) |
| 164 | for i := 0; i < retryCnt; i++ { |
| 165 | fatal, err = t.tryDownloadLocal(lom, timeout) |
| 166 | if err == nil || fatal { |
| 167 | return err |
| 168 | } |
| 169 | if errors.Is(err, context.Canceled) || errors.Is(err, errThrottlerStopped) { |
| 170 | // Download was canceled or stopped, so just return. |
| 171 | return err |
| 172 | } |
| 173 | if errors.Is(err, context.DeadlineExceeded) { |
| 174 | glog.Warningf("%s [retries: %d/%d]: timeout (%v) - increasing and retrying...", |
| 175 | t, i, retryCnt, timeout) |
| 176 | timeout = time.Duration(float64(timeout) * reqTimeoutFactor) |
| 177 | } else if httpErr := cmn.Err2HTTPErr(err); httpErr != nil { |
| 178 | glog.Warningf("%s [retries: %d/%d]: failed to perform request: %v (code: %d)", t, i, retryCnt, err, |
| 179 | httpErr.Status) |
| 180 | if _, exists := terminalStatuses[httpErr.Status]; exists { |
| 181 | // Nothing we can do... |
| 182 | return err |
| 183 | } |
| 184 | // Otherwise retry... |
| 185 | } else if cos.IsRetriableConnErr(err) { |
| 186 | glog.Warningf("%s [retries: %d/%d]: connection failed with (%v), retrying...", t, i, retryCnt, err) |
| 187 | } else { |
| 188 | glog.Warningf("%s [retries: %d/%d]: unexpected error (%v), retrying...", t, i, retryCnt, err) |
| 189 | } |
| 190 | |
| 191 | t.reset() |
| 192 | } |
| 193 | return err |
| 194 | } |
| 195 | |
| 196 | func (t *singleObjectTask) wrapReader(ctx context.Context, r io.ReadCloser) io.ReadCloser { |
| 197 | // Create a custom reader to monitor progress every time we read from response body stream. |
no test coverage detected