We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Access to cache in cli task not working with APC

Hello!

I have CLI Task and i need to work with cache.

UPD: It's strange that Apc handler works bad (always NULL), but Memcache handler working well.

GitHub issue: https://github.com/phalcon/cphalcon/issues/3269

I'm using di like that:

MainTask.php

use Phalcon\CLI\Task;

/**
 * Class MainTask
 *
 * @property \Phalcon\DI\FactoryDefault\CLI $di
 * @property \Phalcon\Cache\Multiple        $cache
 */
class MainTask extends Task
{
    protected $di;
    protected $cache;

    public function mainAction()
    {
        echo "\n\tUsage: $ php cli.php [task] [action] [args ...]\n\n";
        echo "\tAvaiable tasks:\n";
        echo "\t\t– cache\n";
    }

    public function initialize()
    {
        $this->di    = $this->getDI();
        $this->cache = $this->di->getShared('cache');
    }
}

CacheTask.php

use Api\Models\Users;

class CacheTask extends MainTask
{
    public function mainAction()
    {
        echo "\n\tUsage: $ php cli.php generate [action] [args ...]\n\n";
        echo "\tAvaiable tasks:\n";
        echo "\t\t– users\n";
    }

    public function usersAction()
    {
        $id      = 42;
        $key     = "Users_$id";
        $user    = Users::findFirst($id);
        $userArr = $user->toArray();
        $userArr['foobar'] = $user->calculateSomeData();
        $this->cache->save($key, $userArr);
        $userCached = $this->cache->get($key);

        var_export($id);         echo "\n"; // [ OK ]: 42
        var_export($key);        echo "\n"; // [ OK ]: "Users_42"
        var_export($userArr);    echo "\n"; // [ OK ]: array(/* ... */)
        var_export($userCached); echo "\n"; // [FAIL]: NULL
    }
}

Why $userCached is always null? Any data NOT write in cache.

services config

use Phalcon\Cache\Backend\Apc;
use Phalcon\Cache\Backend\Memcache;
use Phalcon\Cache\Frontend\Data;
use Phalcon\Cache\Multiple;
use Phalcon\Db\Adapter\Pdo\Mysql as DbAdapter;
use Phalcon\DI\FactoryDefault as ServerDI;
use Phalcon\DI\FactoryDefault\CLI as CliDI;

// List of all services
$serviceConfig = $config;
$serviceCache  = function () use ($serviceConfig) {
    $frontend = new Data($serviceConfig->cache->frontend->toArray());

    return new Multiple(array(
        // With APC test FAILS, $userCached == NULL
        new Apc($frontend, $serviceConfig->cache->apc->toArray()),
        // With Memcached everithing ok OK, $userCached == array(/**/)
//        new Memcache($frontend, $serviceConfig->cache->memcache->toArray()),
    ));
};
$serviceDb     = function () use ($serviceConfig) {
    return new DbAdapter($serviceConfig->db->toArray());
};

// Config
$sConfig = array(
    'cli'    => array(
        'cache'  => $serviceCache,
        'config' => $serviceConfig,
        'db'     => $serviceDb,
    ),
    'server' => array(
        'cache'  => $serviceCache,
        'config' => $serviceConfig,
        'db'     => $serviceDb,
    ),
);

// Load!
if (php_sapi_name() != 'cli') {
    $sLoadType = 'server';
    $di        = new ServerDI();
}
else {
    $sLoadType = 'cli';
    $di        = new CliDI();
}

foreach ($sConfig[$sLoadType] as $sName => $sCallback)
    $di->setShared($sName, $sCallback);


21.7k

Thank you for answer!

See comment on GitHub.

Yes. Here some configs. Are they okay?

# php -m | grep apc
apc
# cat /etc/php5/conf.d/20-apc.ini
extension=apc.so
apc.enabled = 1
apc.enable_cli = 1
apc.shm_size = 256M

$ php -m | grep apc
apc
$ cat /usr/local/etc/php/5.4/conf.d/ext-apc.ini
[apc]
extension="/usr/local/Cellar/php54-apc/3.1.13/apc.so"
apc.enabled=1
apc.shm_segments=1
apc.shm_size=64M
apc.ttl=7200
apc.user_ttl=7200
apc.num_files_hint=1024
apc.mmap_file_mask=/tmp/apc.XXXXXX
apc.enable_cli=1

Did you enable it?

https://php.net/manual/ru/apc.configuration.php#ini.apc.enable-cli

APC CLI enabled only lets you store things in APC for that run of the script. So when you execute your CLI script the APC cache is created and can be used during your script, but once your cli script ends the APC cache is destroyed and closed. It's worth noting that if you restart your web server (php-fpm or apache) the APC cache is also destroyed and recreated when the service starts up. MemcacheD is a seperate in memory storage system not tied to PHP's runtime environment, so it will live between CLI script executions.

Does that make sense?



21.7k
Accepted
answer
edited Jan '15

I see thread and comments on GitHub issue #3269. Especially @tsnyder91's detailed comment and related answer to StackOwerflow post.

I think, that issue may be closed as "doesn't make sense" anymore. Use memcacheD/Redis/RIAK/usw instead for CLI tasks.