Problem/Motivation
The Drupal\Core\KeyValueStore\DatabaseStorage
uses a configurable serializer to store PHP objects. This serializer is injected as a service in core. The pre-configured serializer used there Drupal\Component\Serialization\PhpSerialize
:
keyvalue.database:
class: Drupal\Core\KeyValueStore\KeyValueDatabaseFactory
arguments: ['@serialization.phpserialize', '@database']
serialization.phpserialize:
class: Drupal\Component\Serialization\PhpSerialize
This architecture allows contrib modules like https://www.drupal.org/project/igbinary to swap the serializer. For example igbinary shrinks the size of larger serialized PHP objects to one third without losing any performance. (In some cases the performance is increased as well.)
Having this kind of memory saving would be a huge benefit for all kind of drupal caches that store serialized PHP objects, especially if there using in memory solutions like memcache. Systems like redis or even the database will benefit from igbinary as well.
Unfortunately the Drupal\Core\Cache\DatabaseBackend
and the Drupal\Core\Cache\MemoryBackend
use a hard-coded PHP serialization. Therefore the could not be easily improved by modules like https://www.drupal.org/project/igbinary
Proposed resolution
Follow the pattern of Drupal\Core\KeyValueStore\DatabaseStorage
and Drupal\Core\KeyValueStore\DatabaseStorageExpirable
and inject the serialize as a service to the Drupal\Core\Cache\DatabaseBackend
.
The default configuration in core should then "remain" as it is and inject Drupal\Component\Serialization\PhpSerialize.
Even if this improvement makes sense for the Drupal\Core\Cache\MemoryBackend
as well, @catch decided to not modify it in core. This backend is heavily used in the tests which will be more complicated afterwards. Therefore the igbinary contrib module will provide it's own backend as drop-in replacement.
As proposed by @berdir we introduce a "new" service serialization.objectaware.default
that is in core just an alias for serialization.phpserialize
. The redis module will leverage this one as well as soon as this patch gets committed. This new default service eases the task for the modules like igbinary to switch (most of) the serilaizers system wide.
Remaining tasks
Review the existing patch.
User interface changes
None.
API changes
Similar to Drupal\Core\KeyValueStore\KeyValueDatabaseFactory
and Drupal\Core\KeyValueStore\DatabaseStorage
the constructor of Drupal\Core\Cache\DatabaseBackend
an its factory need to be prepared for dependency injection.
In addition we define a new interface Drupal\Component\Serialization\ObjectAwareSerializationInterface
that just extends Drupal\Component\Serialization\SerializationInterface
to clearly indicate that implementing Serializers are suitable for PHP Object serialization.
Old:
DatabaseBackendFactory::__construct(Connection $connection, CacheTagsChecksumInterface $checksum_provider);
DatabaseBackend::__construct(Connection $connection, CacheTagsChecksumInterface $checksum_provider, $bin);
New:
interface ObjectAwareSerializationInterface extends SerializationInterface {}
DatabaseBackendFactory::__construct(Connection $connection, CacheTagsChecksumInterface $checksum_provider, ObjectSerializationInterface $serializer = NULL);
DatabaseBackend::__construct(Connection $connection, CacheTagsChecksumInterface $checksum_provider, $bin, ObjectSerializationInterface $serializer = NULL);
These API changes don't break BC!
Data model changes
None.