diff --git a/fastcache.go b/fastcache.go index 8a3268e..c47ea61 100644 --- a/fastcache.go +++ b/fastcache.go @@ -77,7 +77,9 @@ type Item struct { ContentType string Compression string ETag string - Blob []byte + // If the Blob is used beyond the scope of the request, it should be copied. + // Such as when the cache is written asynchronously. + Blob []byte } // Store represents a backend data store where bytes are cached. Individual diff --git a/stores/goredis/redis.go b/stores/goredis/redis.go index 614966f..4376e03 100644 --- a/stores/goredis/redis.go +++ b/stores/goredis/redis.go @@ -169,6 +169,14 @@ type putReq struct { // Put sets a value to given session but stored only on commit func (s *Store) Put(namespace, group, uri string, b fastcache.Item, ttl time.Duration) error { if s.config.Async { + // In async mode, we need to copy b.Blob to prevent fasthttp from reusing + // the buffer, as we will use the buffer in a separate goroutine beyond + // the scope of the current request. + blobCopy := make([]byte, len(b.Blob)) + copy(blobCopy, b.Blob) + b.Blob = blobCopy + + // Send the put request to the async buffer channel. s.putBuf <- putReq{namespace, group, uri, b, ttl} return nil }