Skip to content

[symfony/cache] Big time shifting for items with small TTL #31573

@ilyachase

Description

@ilyachase

Description
Recently we've faced problem with memcached expiry time shifting by +-1 second. This problem corresponds with fact that there is no resolution clock in memcached. So if I set cache with expire time 3 seconds, it will be there at least 2. But when I use symfony/cache wrapper, I as a rule get result with less than 2 seconds. And I don't know why yet. One of the reason may be long execution stack, another is that in Memcached there are two ways to set expiration time: in seconds less than seconds in 30 days, and in timestamp. In symfony/cache wrapper, expiry always sets as time() + expiry_seconds (second option) here: symfony/cache/CacheItem.php:97.

How to reproduce
put following code inside test.php:

<?php

require_once 'vendor/autoload.php';

use Symfony\Component\Cache\Adapter\MemcachedAdapter;

$m = new Memcached();
$m->addServer('localhost', 11211);

$m->set('test', true, (int)$argv[1]);

$time = 0;
while ($m->get('test')) {
    usleep(100 * 1000);
    $time += 0.1;
    var_dump("Memcached: $time");
}

$cacheClient = MemcachedAdapter::createConnection(['memcached://localhost:11211']);
$cache = new MemcachedAdapter($cacheClient);

$item = $cache->getItem('test');
$item->expiresAfter((int)$argv[1]);
$cache->save($item);

$time = 0;
while ($cache->getItem('test')->isHit()) {
    usleep(100 * 1000);
    $time += 0.1;
    var_dump("Symfony: $time");
}

docker run -p 11211:11211 -d memcached
docker run -it --rm --network=host -v $PWD:/src -w /src chialab/php:7.3 php test.php 3

Example output

string(14) "Memcached: 0.1"                                                                                                                                             
string(14) "Memcached: 0.2"                                                                                                                                             
string(14) "Memcached: 0.3"                                                                                                                                             
string(14) "Memcached: 0.4"                                                                                                                                             
...                                                                                                                                    
string(14) "Memcached: 2.6"                                                                                                                                             
string(14) "Memcached: 2.7"                                                                                                                                             
string(14) "Memcached: 2.8"                                                                                                                                             
string(12) "Symfony: 0.1"                                                                                                                                               
string(12) "Symfony: 0.2"                                                                                                                                               
string(12) "Symfony: 0.3"                                                                                                                                               
...                                                                                                                                    
string(12) "Symfony: 1.7"                                                                                                                                               
string(12) "Symfony: 1.8"

You can run it hundred times and through symfony/cache, cache will not leave at least 2 seconds.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions