(ctx context.Context, node RemoteNode)
| 471 | } |
| 472 | |
| 473 | func (r *Reader) readRemoteNodeContent(ctx context.Context, node RemoteNode) ([]byte, error) { |
| 474 | cache := NewCacheNode(node, r.tempDir) |
| 475 | now := time.Now().UTC() |
| 476 | timestamp := cache.ReadTimestamp() |
| 477 | expiry := timestamp.Add(r.cacheExpiryDuration) |
| 478 | cacheValid := now.Before(expiry) |
| 479 | var cacheFound bool |
| 480 | |
| 481 | r.debugf("checking cache for %q in %q\n", node.Location(), cache.Location()) |
| 482 | cachedBytes, err := cache.Read() |
| 483 | switch { |
| 484 | // If the cache doesn't exist, we need to download the file |
| 485 | case errors.Is(err, os.ErrNotExist): |
| 486 | r.debugf("no cache found\n") |
| 487 | // If we couldn't find a cached copy, and we are offline, we can't do anything |
| 488 | if r.offline { |
| 489 | return nil, &errors.TaskfileCacheNotFoundError{ |
| 490 | URI: node.Location(), |
| 491 | } |
| 492 | } |
| 493 | |
| 494 | // If the cache is expired |
| 495 | case !cacheValid: |
| 496 | r.debugf("cache expired at %s\n", expiry.Format(time.RFC3339)) |
| 497 | cacheFound = true |
| 498 | // If we can't fetch a fresh copy, we should use the cache anyway |
| 499 | if r.offline { |
| 500 | r.debugf("in offline mode, using expired cache\n") |
| 501 | return cachedBytes, nil |
| 502 | } |
| 503 | |
| 504 | // Some other error |
| 505 | case err != nil: |
| 506 | return nil, err |
| 507 | |
| 508 | // Found valid cache |
| 509 | default: |
| 510 | r.debugf("cache found\n") |
| 511 | // Not being forced to redownload, return cache |
| 512 | if !r.download { |
| 513 | return cachedBytes, nil |
| 514 | } |
| 515 | cacheFound = true |
| 516 | } |
| 517 | |
| 518 | // Try to read the remote file |
| 519 | r.debugf("downloading remote file: %s\n", node.Location()) |
| 520 | downloadedBytes, err := node.ReadContext(ctx) |
| 521 | if err != nil { |
| 522 | // If the context timed out or was cancelled, but we found a cached version, use that |
| 523 | if ctx.Err() != nil && cacheFound { |
| 524 | if cacheValid { |
| 525 | r.debugf("failed to fetch remote file: %s: using cache\n", ctx.Err().Error()) |
| 526 | } else { |
| 527 | r.debugf("failed to fetch remote file: %s: using expired cache\n", ctx.Err().Error()) |
| 528 | } |
| 529 | return cachedBytes, nil |
| 530 | } |
no test coverage detected