Problem/Motivation
When using memcache for multiple cache bins, I get a ServiceNotFoundException for a non existant service.
The output after running drush status
KEYS getMulti:array (
'bootstrap-last_write_timestamp_cache_bootstrap' => '-bootstrap-last_write_timestamp_cache_bootstrap',
)
KEYS getMulti:array (
'bootstrap-system_list' => '-bootstrap-system_list',
)
KEYS getMulti:array (
'discovery-last_write_timestamp_cache_discovery' => '-discovery-last_write_timestamp_cache_discovery',
)
KEYS getMulti:array (
'discovery-entity_type' => '-discovery-entity_type',
)
KEYS getMulti:array (
'entity-values:user:0' => '-entity-values%3Auser%3A0',
)
KEYS getMulti:array (
'discovery-entity_base_field_definitions:user:de' => '-discovery-entity_base_field_definitions%3Auser%3Ade',
)
KEYS getMulti:array (
'discovery-entity_field_storage_definitions:user:de' => '-discovery-entity_field_storage_definitions%3Auser%3Ade',
)
Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException: You have requested a non-existent service "user.field_user_food_blogger". in Drupal\Component\DependencyInjection\Container->get() (line 157 of [error]
/var/www/docroot/core/lib/Drupal/Component/DependencyInjection/Container.php) #0
/var/www/docroot/core/lib/Drupal/Core/DependencyInjection/DependencySerializationTrait.php(53): Drupal\Component\DependencyInjection\Container->get('user.field_user...')
#1 [internal function]: Drupal\Core\Entity\Entity->__wakeup()
#2 /var/www/docroot/modules/contrib/memcache/src/DrupalMemcached.php(88): Memcached->getMulti(Array, NULL, 1)
#3 /var/www/docroot/modules/contrib/memcache/src/MemcacheBackend.php(101): Drupal\memcache\DrupalMemcached->getMulti(Array)
#4 /var/www/docroot/core/lib/Drupal/Core/Cache/ChainedFastBackend.php(165): Drupal\memcache\MemcacheBackend->getMultiple(Array, false)
#5 /var/www/docroot/core/lib/Drupal/Core/Cache/ChainedFastBackend.php(103): Drupal\Core\Cache\ChainedFastBackend->getMultiple(Array, false)
#6 /var/www/docroot/core/lib/Drupal/Core/Cache/UseCacheBackendTrait.php(37): Drupal\Core\Cache\ChainedFastBackend->get('entity_field_st...')
#7 /var/www/docroot/core/lib/Drupal/Core/Entity/EntityFieldManager.php(401): Drupal\Core\Entity\EntityFieldManager->cacheGet('entity_field_st...')
#8 /var/www/docroot/core/lib/Drupal/Core/Entity/EntityManager.php(154): Drupal\Core\Entity\EntityFieldManager->getFieldStorageDefinitions('user')
#9 /var/www/docroot/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php(282): Drupal\Core\Entity\EntityManager->getFieldStorageDefinitions('user')
#10 /var/www/docroot/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php(665): Drupal\Core\Entity\Sql\SqlContentEntityStorage->getTableMapping()
#11 /var/www/docroot/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php(428): Drupal\Core\Entity\Sql\SqlContentEntityStorage->buildQuery(Array)
#12 /var/www/docroot/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php(399): Drupal\Core\Entity\Sql\SqlContentEntityStorage->getFromStorage(Array)
#13 /var/www/docroot/core/lib/Drupal/Core/Entity/EntityStorageBase.php(242): Drupal\Core\Entity\Sql\SqlContentEntityStorage->doLoadMultiple(Array)
#14 /var/www/docroot/core/lib/Drupal/Core/Entity/EntityStorageBase.php(212): Drupal\Core\Entity\EntityStorageBase->loadMultiple(Array)
#15 /var/www/docroot/core/lib/Drupal/Core/Entity/Entity.php(499): Drupal\Core\Entity\EntityStorageBase->load(0)
#16 /var/www/vendor/drush/drush/lib/Drush/User/User8.php(26): Drupal\Core\Entity\Entity::load(0)
#17 /var/www/vendor/drush/drush/lib/Drush/Boot/DrupalBoot.php(558): Drush\User\User8->load_by_uid(0)
#18 /var/www/vendor/drush/drush/includes/bootstrap.inc(354): Drush\Boot\DrupalBoot->bootstrap_drupal_login()
#19 /var/www/vendor/drush/drush/includes/bootstrap.inc(509): drush_bootstrap(6, 7)
#20 /var/www/vendor/drush/drush/includes/bootstrap.inc(456): drush_bootstrap_max()
#21 /var/www/vendor/drush/drush/lib/Drush/Boot/BaseBoot.php(59): drush_bootstrap_to_phase(-2)
#22 /var/www/vendor/drush/drush/includes/preflight.inc(66): Drush\Boot\BaseBoot->bootstrap_and_dispatch()
#23 /var/www/vendor/drush/drush/drush.php(12): drush_main()
#24 {main}.
Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException: You have requested a non-existent service "user.field_user_food_blogger". in Drupal\Component\DependencyInjection\Container->get() (line 157 of /var/www/docroot/core/lib/Drupal/Component/DependencyInjection/Container.php).
Settings.local.php
$settings['memcache']['servers'] = ['localhost:11211' => 'default'];
$settings['memcache']['bins'] = ['default' => 'default'];
$settings['memcache']['key_prefix'] = '';
$settings['memcache']['stampede_protection'] = TRUE;
$settings['cache']['default'] = 'cache.backend.memcache';
$settings['cache']['bins']['cache_container'] = 'cache.backend.memcache';
$settings['cache']['bins']['cache_library'] = 'cache.backend.memcache';
$settings['cache']['bins']['cache_menu'] = 'cache.backend.memcache';
$settings['cache']['bins']['entity'] = 'cache.backend.memcache';
// APCu chainedfast backends
$settings['cache']['bins']['bootstrap'] = 'cache.backend.chainedfast';
$settings['cache']['bins']['config'] = 'cache.backend.chainedfast';
$settings['cache']['bins']['discovery'] = 'cache.backend.chainedfast';
// database cache
$settings['cache']['bins']['data'] = 'cache.backend.database';
$settings['cache']['bins']['riddle_feed'] = 'cache.backend.database';
$settings['cache']['bins']['tweets'] = 'cache.backend.database';
// Debugging
$settings['cache']['bins']['dynamic_page_cache'] = 'cache.backend.memory';
$settings['cache']['bins']['render'] = 'cache.backend.memory';
docker-compose.yml
I use a docker image to run the memcached service. Apache and MySQL are run via MAMP.
version: "2"
services:
memcached:
image: memcached:1.4-alpine
ports:
- "11211:11211"
mem_limit: 1g
command: memcached -m 1024m
memcached-admin:
image: phynias/phpmemcachedadmin
ports:
- "8006:80"
Analysis
The debug lines above are coming from print "\nKEYS getMulti:" . var_export($full_keys, TRUE) . "\n";
being added to \Drupal\memcache\DrupalMemcached::getMulti()
so I could understand what key is causing the issue.
It seems like odd data is passed to \Drupal\Core\DependencyInjection\DependencySerializationTrait::__wakeup()
by memcache. When I inspect the object in xdebug, the object does not have proper _serviceIds, but its own object put int _serviceIds: see http://share.undpaul.de/bilder/jh/memcached-service-ids-wakup.png.
When using phpmemcachedadmin I could not grab the key -discovery-entity_field_storage_definitions%3Auser%3Ade
via the interface, allthough it was listed in the search when searching for -discovery-entity_field_storage_definitions
. So I experimentally changed \Drupal\memcache\DrupalMemcacheBase::key
to allways use hash()
. With doing that, everything worked fine. So I think it has something to do with special characters or the url-encoding.
Proposed resolution
* ?
Remaining tasks
* Check if there are any issues with special characters, like :
in memcached.
API changes
* ?
Data model changes
Comment | File | Size | Author |
---|---|---|---|
#9 | 2865364-8.patch | 514 bytes | catch |
#5 | 2865364.patch | 822 bytes | damiankloip |
Comments
Comment #2
derhasi CreditAttribution: derhasi at undpaul commentedI was wrong. When always using hash(), I still run into the issue. But at least now I can get the data from the memcache server. But I do not knwo why this data should be corrupt:
Comment #3
MiSc CreditAttribution: MiSc at Wunder commentedDo you get the same result if you only use memcache?
Comment #4
damiankloip CreditAttribution: damiankloip commentedMemcache currently clones objects if the $data passed to a set() call is an object. That could be the source of your problems here?
Comment #5
damiankloip CreditAttribution: damiankloip commentedLet me know if this fixes the issue for you, thanks!
Comment #6
damiankloip CreditAttribution: damiankloip commented@derhasi any news on this? It would be good to get your testing as the original bug reporter. Seems like it should be an OK change generally though.
Comment #7
webchickTagging as a stable release blocker, per #2989594: [META] Create a stable release of Memcache module for Drupal 8.
Comment #8
catchThis no longer applied, so I've re-rolled it.
I removed
I removed this hunk because $cache->serialized is used exclusively and internally by the core database cache backend.
Removing the clone looks sensible to me, other backends don't do this (apart from the MemoryBackend which is special), so moving to RTBC since all I've done here is review and re-roll.
Comment #9
catchComment #10
Jeremy CreditAttribution: Jeremy at Tag1 Consulting commentedComment #11
Fabianx CreditAttribution: Fabianx at Tag1 Consulting for Acquia commentedEven though we do clone in 7.x, no other 8.x cache backend clones AND the semantics of __clone are different from __serialize.
e.g.
clone $obj != unserialize(serialize($obj))
it can be different in certain cases.
And if an object prevents cloning, but allows serialize it would work with DB backend + APCu backend, but not memcache backend and that is bad.
So RTBC + 1.
Comment #12
Fabianx CreditAttribution: Fabianx at Tag1 Consulting for Acquia commentedPotentially should be backported to D7 as there is really no need to clone with memcache.db.inc gone.
Comment #14
catch