(key *Key)
| 95 | } |
| 96 | |
| 97 | func (r *redisCache) Get(key *Key) (*CachedData, error) { |
| 98 | ctx, cancelFunc := context.WithTimeout(context.Background(), getTimeout) |
| 99 | defer cancelFunc() |
| 100 | nbBytesToFetch := int64(100 * 1024) |
| 101 | stringKey := key.String() |
| 102 | // fetching 100kBytes from redis to be sure to have the full metadata and, |
| 103 | // for most of the queries that fetch a few data, the cached results |
| 104 | val, err := r.client.GetRange(ctx, stringKey, 0, nbBytesToFetch).Result() |
| 105 | |
| 106 | // errors, such as timeouts |
| 107 | if err != nil { |
| 108 | log.Errorf("failed to get key %s with error: %s", stringKey, err) |
| 109 | return nil, ErrMissing |
| 110 | } |
| 111 | // if key not found in cache |
| 112 | if len(val) == 0 { |
| 113 | return nil, ErrMissing |
| 114 | } |
| 115 | |
| 116 | ttl, err := r.client.TTL(ctx, stringKey).Result() |
| 117 | if err != nil { |
| 118 | return nil, fmt.Errorf("failed to ttl of key %s with error: %w", stringKey, err) |
| 119 | } |
| 120 | b := []byte(val) |
| 121 | metadata, offset, err := r.decodeMetadata(b) |
| 122 | if err != nil { |
| 123 | if errors.Is(err, &RedisCacheCorruptionError{}) { |
| 124 | log.Errorf("an error happened while handling redis key =%s, err=%s", stringKey, err) |
| 125 | } |
| 126 | return nil, err |
| 127 | } |
| 128 | if (int64(offset) + metadata.Length) < nbBytesToFetch { |
| 129 | // the condition is true ony if the bytes fetched contain the metadata + the cached results |
| 130 | // so we extract from the remaining bytes the cached results |
| 131 | payload := b[offset:] |
| 132 | reader := &ioReaderDecorator{Reader: bytes.NewReader(payload)} |
| 133 | value := &CachedData{ |
| 134 | ContentMetadata: *metadata, |
| 135 | Data: reader, |
| 136 | Ttl: ttl, |
| 137 | } |
| 138 | |
| 139 | return value, nil |
| 140 | } |
| 141 | |
| 142 | return r.readResultsAboveLimit(offset, stringKey, metadata, ttl) |
| 143 | } |
| 144 | |
| 145 | func (r *redisCache) readResultsAboveLimit(offset int, stringKey string, metadata *ContentMetadata, ttl time.Duration) (*CachedData, error) { |
| 146 | // since the cached results in redis are too big, we can't fetch all of them because of the memory overhead. |
nothing calls this directly
no test coverage detected