in internal/gcsx/file_cache_reader.go [88:169]
func (fc *FileCacheReader) tryReadingFromFileCache(ctx context.Context, p []byte, offset int64) (int, bool, error) {
if fc.fileCacheHandler == nil {
return 0, false, nil
}
// By default, consider read type random if the offset is non-zero.
isSequential := offset == 0
var handleID uint64
if readOp, ok := ctx.Value(ReadOp).(*fuseops.ReadFileOp); ok {
handleID = uint64(readOp.Handle)
}
requestID := uuid.New()
logger.Tracef("%.13v <- FileCache(%s:/%s, offset: %d, size: %d, handle: %d)", requestID, fc.bucket.Name(), fc.object.Name, offset, len(p), handleID)
startTime := time.Now()
var bytesRead int
var cacheHit bool
var err error
defer func() {
executionTime := time.Since(startTime)
var requestOutput string
if err != nil {
requestOutput = fmt.Sprintf("err: %v (%v)", err, executionTime)
} else {
if fc.fileCacheHandle != nil {
isSequential = fc.fileCacheHandle.IsSequential(offset)
}
requestOutput = fmt.Sprintf("OK (isSeq: %t, cacheHit: %t) (%v)", isSequential, cacheHit, executionTime)
}
logger.Tracef("%.13v -> %s", requestID, requestOutput)
readType := util.Random
if isSequential {
readType = util.Sequential
}
captureFileCacheMetrics(ctx, fc.metricHandle, readType, bytesRead, cacheHit, executionTime)
}()
// Create fileCacheHandle if not already.
if fc.fileCacheHandle == nil {
fc.fileCacheHandle, err = fc.fileCacheHandler.GetCacheHandle(fc.object, fc.bucket, fc.cacheFileForRangeRead, offset)
if err != nil {
switch {
case errors.Is(err, lru.ErrInvalidEntrySize):
logger.Warnf("tryReadingFromFileCache: while creating CacheHandle: %v", err)
return 0, false, nil
case errors.Is(err, cacheUtil.ErrCacheHandleNotRequiredForRandomRead):
// Fall back to GCS if it is a random read, cacheFileForRangeRead is
// false and there doesn't already exist file in cache.
isSequential = false
return 0, false, nil
default:
return 0, false, fmt.Errorf("tryReadingFromFileCache: GetCacheHandle failed: %w", err)
}
}
}
bytesRead, cacheHit, err = fc.fileCacheHandle.Read(ctx, fc.bucket, fc.object, offset, p)
if err == nil {
return bytesRead, cacheHit, nil
}
bytesRead = 0
cacheHit = false
if cacheUtil.IsCacheHandleInvalid(err) {
logger.Tracef("Closing cacheHandle:%p for object: %s:/%s", fc.fileCacheHandle, fc.bucket.Name(), fc.object.Name)
closeErr := fc.fileCacheHandle.Close()
if closeErr != nil {
logger.Warnf("tryReadingFromFileCache: close cacheHandle error: %v", closeErr)
}
fc.fileCacheHandle = nil
} else if !errors.Is(err, cacheUtil.ErrFallbackToGCS) {
return 0, false, fmt.Errorf("tryReadingFromFileCache: while reading via cache: %w", err)
}
err = nil
return 0, false, nil
}