diff --git a/src/MemcacheBackend.php b/src/MemcacheBackend.php index ff5cf31..c4f646d 100644 --- a/src/MemcacheBackend.php +++ b/src/MemcacheBackend.php @@ -7,6 +7,7 @@ namespace Drupal\memcache; +use Drupal\Component\Utility\Crypt; use Drupal\Core\Cache\Cache; use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Cache\CacheTagsChecksumInterface; @@ -257,13 +258,21 @@ class MemcacheBackend implements CacheBackendInterface { $data = serialize($item->data); $pieces = str_split($data, static::MAX_CHUNK_SIZE); + // Add a unique identifier each time this function is invoked. This + // prevents a race condition where two sets on the same multipart item can + // clobber each other's children. With this seed, each time a multipart + // entry is created, they get a different CID. The parent (multipart) entry + // does not inherit this unique identifier, so it is still addressable using + // the CID it was initially given. + $seed = Crypt::randomBytesBase64(); + $children = []; foreach ($pieces as $i => $chunk) { // Child items do not need tags or expire, since that data is carried by // the parent. $chunkItem = new \stdClass(); - $chunkItem->cid = sprintf('%s.%d', $item->cid, $i); + $chunkItem->cid = sprintf('%s.%s.%d', $item->cid, $seed, $i); $chunkItem->data = $chunk; $chunkItem->created = $item->created; $children[] = $chunkItem;