Skip to content
This repository has been archived by the owner on Nov 25, 2020. It is now read-only.

Commit

Permalink
Adding chain cache for nodes data
Browse files Browse the repository at this point in the history
  • Loading branch information
ghecquet committed Jun 29, 2016
1 parent 950368a commit cb2166d
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 15 deletions.
18 changes: 17 additions & 1 deletion core/src/plugins/cache.doctrine/DoctrineCacheDriver.php
Expand Up @@ -31,7 +31,11 @@
define('XCACHE_EXTENSION_LOADED', extension_loaded('xcache')); define('XCACHE_EXTENSION_LOADED', extension_loaded('xcache'));


use \Doctrine\Common\Cache; use \Doctrine\Common\Cache;
use Doctrine\Common\Cache\ArrayCache;
use Doctrine\Common\Cache\ChainCache;
use Pydio\Cache\Core\AbstractCacheDriver; use Pydio\Cache\Core\AbstractCacheDriver;
use Pydio\Cache\Doctrine\Ext\PydioChainCache;
use Pydio\Core\Model\Context;
use Pydio\Core\Model\ContextInterface; use Pydio\Core\Model\ContextInterface;
use Pydio\Core\Utils\ApplicationState; use Pydio\Core\Utils\ApplicationState;
use Pydio\Core\Utils\Vars\StringHelper; use Pydio\Core\Utils\Vars\StringHelper;
Expand Down Expand Up @@ -115,7 +119,7 @@ public function init(ContextInterface $ctx, $options = [])
*/ */
private function initCacheWithNamespace($namespace){ private function initCacheWithNamespace($namespace){
$cacheDriver = null; $cacheDriver = null;
$emptyContext = \Pydio\Core\Model\Context::emptyContext(); $emptyContext = Context::emptyContext();
$driverOptions = $this->getContextualOption($emptyContext, "DRIVER"); $driverOptions = $this->getContextualOption($emptyContext, "DRIVER");
$cachePrefix = $this->getContextualOption($emptyContext, "CACHE_PREFIX"); $cachePrefix = $this->getContextualOption($emptyContext, "CACHE_PREFIX");


Expand Down Expand Up @@ -150,7 +154,19 @@ private function initCacheWithNamespace($namespace){
if(empty($cachePrefix)){ if(empty($cachePrefix)){
$cachePrefix = StringHelper::slugify(ApplicationState::detectServerURL(true)); $cachePrefix = StringHelper::slugify(ApplicationState::detectServerURL(true));
} }

$cachePrefix .= "_".$namespace."_"; $cachePrefix .= "_".$namespace."_";

// Using chained array for nodes
if ($namespace == AJXP_CACHE_SERVICE_NS_NODES) {
$arrayCache = new ArrayCache();

$cacheDriver = new PydioChainCache([
$arrayCache,
$cacheDriver
]);
}

$cacheDriver->setNamespace($cachePrefix); $cacheDriver->setNamespace($cachePrefix);
return $cacheDriver; return $cacheDriver;


Expand Down
11 changes: 6 additions & 5 deletions core/src/plugins/cache.doctrine/src/PydioApcuCache.php
Expand Up @@ -20,13 +20,15 @@
*/ */
namespace Pydio\Cache\Doctrine\Ext; namespace Pydio\Cache\Doctrine\Ext;


use Doctrine\Common\Cache\ApcuCache;

defined('AJXP_EXEC') or die('Access not allowed'); defined('AJXP_EXEC') or die('Access not allowed');


/** /**
* Class PydioApcuCache * Class PydioApcuCache
* @package Pydio\Cache\Doctrine\Ext * @package Pydio\Cache\Doctrine\Ext
*/ */
class PydioApcuCache extends \Doctrine\Common\Cache\ApcuCache implements PatternClearableCache class PydioApcuCache extends ApcuCache implements PatternClearableCache
{ {
protected $internalNamespace; protected $internalNamespace;
protected $internalNamespaceVersion; protected $internalNamespaceVersion;
Expand All @@ -38,17 +40,16 @@ class PydioApcuCache extends \Doctrine\Common\Cache\ApcuCache implements Pattern
* *
* @return string The namespaced id. * @return string The namespaced id.
*/ */
private function namespacedIdAsPattern($id) private function namespacedIdAsPattern($id) {
{
return sprintf('%s\['.preg_quote($id, "/"), $this->internalNamespace); return sprintf('%s\['.preg_quote($id, "/"), $this->internalNamespace);
} }


/** /**
* @param string $pattern * @param string $pattern
* @return bool * @return bool
*/ */
public function deleteKeysStartingWith($pattern) public function deleteKeysStartingWith($pattern) {
{
$pattern = '/^'.$this->namespacedIdAsPattern($pattern).'/'; $pattern = '/^'.$this->namespacedIdAsPattern($pattern).'/';
//SAMPLE /^pydio-unique-id_nodes_\[list\:\/\/1/ //SAMPLE /^pydio-unique-id_nodes_\[list\:\/\/1/
$iterator = new \APCIterator('user', $pattern); $iterator = new \APCIterator('user', $pattern);
Expand Down
56 changes: 56 additions & 0 deletions core/src/plugins/cache.doctrine/src/PydioChainCache.php
@@ -0,0 +1,56 @@
<?php
/**
* Created by PhpStorm.
* User: ghecquet
* Date: 29/06/16
* Time: 10:07
*/

namespace Pydio\Cache\Doctrine\Ext;


use Doctrine\Common\Cache\ChainCache;

class PydioChainCache extends ChainCache implements PatternClearableCache {
/**
* @var Redis
*/
protected $cacheProviders;

protected $internalNamespace;
protected $internalNamespaceVersion;


public function __construct($cacheProviders)
{
parent::__construct($cacheProviders);

$this->cacheProviders = $cacheProviders;
}

/**
* @param string $pattern
* @return bool
*/
public function deleteKeysStartingWith($pattern) {
foreach ($this->cacheProviders as $cache) {

if(!($cache instanceof PatternClearableCache)) {
break;
}

/** @var PatternClearableCache $cache */
$pattern = $cache->deleteKeysStartingWith($pattern);
}
}

/**
* @param string $namespace
* @return void
*/
public function setNamespace($namespace) {
foreach ($this->cacheProviders as $cache) {
$cache->setNamespace($namespace);
}
}
}
3 changes: 2 additions & 1 deletion core/src/plugins/cache.doctrine/src/PydioRedisCache.php
Expand Up @@ -21,14 +21,15 @@
namespace Pydio\Cache\Doctrine\Ext; namespace Pydio\Cache\Doctrine\Ext;
defined('AJXP_EXEC') or die('Access not allowed'); defined('AJXP_EXEC') or die('Access not allowed');


use Doctrine\Common\Cache\RedisCache;
use Redis; use Redis;




/** /**
* Class PydioRedisCache * Class PydioRedisCache
* @package Pydio\Cache\Doctrine\Ext * @package Pydio\Cache\Doctrine\Ext
*/ */
class PydioRedisCache extends \Doctrine\Common\Cache\RedisCache implements PatternClearableCache class PydioRedisCache extends RedisCache implements PatternClearableCache
{ {
/** /**
* @var Redis * @var Redis
Expand Down
29 changes: 22 additions & 7 deletions core/src/plugins/core.access/src/Stream/MetadataCachingStream.php
Expand Up @@ -10,6 +10,9 @@
use GuzzleHttp\Stream\StreamDecoratorTrait; use GuzzleHttp\Stream\StreamDecoratorTrait;
use GuzzleHttp\Stream\StreamInterface; use GuzzleHttp\Stream\StreamInterface;
use Pydio\Access\Core\Model\AJXP_Node; use Pydio\Access\Core\Model\AJXP_Node;
use Pydio\Cache\Core\AbstractCacheDriver;
use Pydio\Cache\Core\CacheStreamLayer;
use Pydio\Core\Services\CacheService;


/** /**
* Stream decorator that can cache previously read bytes from a sequentially * Stream decorator that can cache previously read bytes from a sequentially
Expand All @@ -22,6 +25,9 @@ class MetadataCachingStream implements StreamInterface
/** @var array stat */ /** @var array stat */
private static $stat; private static $stat;


/** @var AJXP_Node node */
private $node;

/** @var string uri */ /** @var string uri */
private $uri; private $uri;


Expand All @@ -31,6 +37,9 @@ class MetadataCachingStream implements StreamInterface
/** @var string path */ /** @var string path */
private $path; private $path;


/** @var string statCacheId */
private $cacheId;

/** /**
* We will treat the buffer object as the body of the stream * We will treat the buffer object as the body of the stream
* *
Expand All @@ -43,7 +52,9 @@ public function __construct(
AJXP_Node $node, AJXP_Node $node,
StreamInterface $target = null StreamInterface $target = null
) { ) {
$this->node = $node;
$this->uri = $node->getUrl(); $this->uri = $node->getUrl();
$this->cacheId = AbstractCacheDriver::computeIdForNode($node, "meta");
$this->contentFilters = $node->getRepository()->getContentFilter()->filters; $this->contentFilters = $node->getRepository()->getContentFilter()->filters;
$this->path = parse_url($this->uri, PHP_URL_PATH); $this->path = parse_url($this->uri, PHP_URL_PATH);


Expand Down Expand Up @@ -90,9 +101,10 @@ public function getContents() {
} }


public function stat() { public function stat() {
if (isset(self::$stat[$this->uri])) {
return self::$stat[$this->uri]; $stat = CacheService::fetch(AJXP_CACHE_SERVICE_NS_NODES, $this->cacheId);
}
if(is_array($stat)) return $stat;


$stats = $this->stream->stat(); $stats = $this->stream->stat();


Expand All @@ -106,13 +118,16 @@ public function stat() {
$path = $this->contentFilters[$path]; $path = $this->contentFilters[$path];
} }


$key = rtrim($this->uri . $path, "/"); $node = new AJXP_Node($this->uri . "/" . $path);
self::$stat[$key] = $stat;
$id = AbstractCacheDriver::computeIdForNode($node, "meta");

CacheService::save(AJXP_CACHE_SERVICE_NS_NODES, $id, $stat);
} }
} else { } else {
self::$stat[$this->uri] = $stats; CacheService::save(AJXP_CACHE_SERVICE_NS_NODES, $this->cacheId, $stats);
} }


return self::$stat[$this->uri]; return CacheService::fetch(AJXP_CACHE_SERVICE_NS_NODES, $this->cacheId);
} }
} }
2 changes: 1 addition & 1 deletion core/src/plugins/core.cache/CoreCacheLoader.php
Expand Up @@ -69,7 +69,7 @@ public function getImplementation($pluginsService = null)
} }
self::$cacheInstance = $pluginInstance; self::$cacheInstance = $pluginInstance;
if($pluginInstance !== null && $pluginInstance instanceof AbstractCacheDriver && $pluginInstance->supportsPatternDelete(AJXP_CACHE_SERVICE_NS_NODES)){ if($pluginInstance !== null && $pluginInstance instanceof AbstractCacheDriver && $pluginInstance->supportsPatternDelete(AJXP_CACHE_SERVICE_NS_NODES)){
//MetaStreamWrapper::appendMetaWrapper("pydio.cache", "\\Pydio\\Cache\\Core\\CacheStreamLayer"); MetaStreamWrapper::appendMetaWrapper("pydio.cache", "\\Pydio\\Cache\\Core\\CacheStreamLayer");
} }
} }


Expand Down

0 comments on commit cb2166d

Please sign in to comment.