Permalink
Browse files

Change keys naming for stat / node.info / list in cache to more easil…

…y empty the cache for a given workspace.
  • Loading branch information...
1 parent db19b3a commit 2a4101b612dcc8bf4c0e1f1316b87a5f24e64e03 @cdujeu cdujeu committed Jun 21, 2016
@@ -63,6 +63,9 @@
abstract public function getCacheDriver($namespace=AJXP_CACHE_SERVICE_NS_SHARED);
/**
+ * Compute a cache ID for a given node. Will be in the form
+ * cacheType://repositoryId/userSepcificKey|shared/nodePath[##detail]
+ *
* @param AJXP_Node $node
* @param string $cacheType
* @param string $details
@@ -71,19 +74,34 @@
public static function computeIdForNode($node, $cacheType, $details = ''){
$ctx = $node->getContext();
$repo = $node->getRepository();
- $user = $ctx->getUser();
if($repo == null) return "failed-id";
$scope = $repo->securityScope();
- $additional = "";
- if($scope === "USER"){
- $additional = ($user!==null ? $user->getId() : "shared")."@";
+ $userId = $node->getUserId();
+ // Compute second segment
+ if($userId === "*"){
+ $subPath = "";
+ }else if($scope === "USER"){
+ $subPath = "/".$userId;
}else if($scope == "GROUP"){
$gPath = "/";
+ $user = $ctx->getUser();
if($user !== null) $gPath = $user->getGroupPath();
- $additional = ltrim(str_replace("/", "__", $gPath), "__")."@";
+ $subPath = "/".ltrim(str_replace("/", "__", $gPath), "__");
+ }else{
+ $subPath = "/shared";
}
- $scheme = parse_url($node->getUrl(), PHP_URL_SCHEME);
- return str_replace($scheme . "://", $cacheType."://".$additional, $node->getUrl()).($details?"##".$details:"");
+ $ID = $cacheType."://".$repo->getId().$subPath.$node->getPath().($details?"##$details":"");
+ return $ID;
+ }
+
+ /**
+ * Same as computeIdForNode but maybe used if a repository has been deleted
+ * @param $repositoryId
+ * @param $cacheType
+ * @return string
+ */
+ public static function computeFullRepositoryId($repositoryId, $cacheType){
+ return $ID = $cacheType."://".$repositoryId."/";
}
/**
@@ -19,16 +19,20 @@
* The latest code can be found at <http://pyd.io/>.
*/
namespace Pydio\Cache\Core;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
use Pydio\Access\Core\AJXP_MetaStreamWrapper;
use Pydio\Access\Core\Model\Repository;
use Pydio\Core\Model\Context;
+use Pydio\Core\Model\ContextInterface;
use Pydio\Core\PluginFramework\CoreInstanceProvider;
use Pydio\Core\Services\CacheService;
use Pydio\Core\Services\ConfService;
-use Pydio\Core\Controller\HTMLWriter;
use Pydio\Core\PluginFramework\Plugin;
use Pydio\Core\PluginFramework\PluginsService;
use Pydio\Access\Core\Model\AJXP_Node;
+use Pydio\Core\Utils\Utils;
+use Zend\Diactoros\Response\JsonResponse;
defined('AJXP_EXEC') or die( 'Access not allowed');
@@ -128,36 +132,57 @@ public function clearNodeInfoCache($from=null, $to=null, $copy = false){
}
/**
+ * Hooked to workspace.after_update event
+ * @param ContextInterface $ctx
* @param Repository $repositoryObject
*/
- public function clearWorkspaceNodeInfos($repositoryObject){
+ public function onWorkspaceUpdate(ContextInterface $ctx, $repositoryObject){
+ $this->clearWorkspaceCache($repositoryObject->getId());
+ }
+
+ /**
+ * Hooked to workspace.after_delete event
+ * @param ContextInterface $ctx
+ * @param string $repositoryId
+ */
+ public function onWorkspaceDelete(ContextInterface $ctx, $repositoryId){
+ $this->clearWorkspaceCache($repositoryId);
+ }
+
+ /**
+ * Util to clear all caches (node.info, stat, list) for a workspace (any users).
+ * @param $repositoryId
+ */
+ private function clearWorkspaceCache($repositoryId){
$cDriver = ConfService::getCacheDriverImpl();
if(empty($cDriver) || !($cDriver->supportsPatternDelete(AJXP_CACHE_SERVICE_NS_NODES))){
return;
}
- $node = new AJXP_Node("pydio://".$repositoryObject->getId()."/");
- $node->setLeaf(false);
- $this->clearCacheForNode($node);
+ $cDriver->deleteKeyStartingWith(AJXP_CACHE_SERVICE_NS_NODES, AbstractCacheDriver::computeFullRepositoryId($repositoryId, "node.info"));
+ $cDriver->deleteKeyStartingWith(AJXP_CACHE_SERVICE_NS_NODES, AbstractCacheDriver::computeFullRepositoryId($repositoryId, "stat"));
+ $cDriver->deleteKeyStartingWith(AJXP_CACHE_SERVICE_NS_NODES, AbstractCacheDriver::computeFullRepositoryId($repositoryId, "list"));
}
/**
* @param \Pydio\Access\Core\Model\AJXP_Node $node
*/
protected function clearCacheForNode($node){
+ $cacheDriver = ConfService::getCacheDriverImpl();
+ if($cacheDriver === null) {
+ return;
+ }
+ // Clear meta for this node
+ $cacheDriver->delete(AJXP_CACHE_SERVICE_NS_NODES, $this->computeId($node, true));
+ $cacheDriver->delete(AJXP_CACHE_SERVICE_NS_NODES, $this->computeId($node, false));
if($node->isLeaf()){
- // Clear meta
- CacheService::delete(AJXP_CACHE_SERVICE_NS_NODES, $this->computeId($node, true));
- CacheService::delete(AJXP_CACHE_SERVICE_NS_NODES, $this->computeId($node, false));
// Clear stat
- CacheService::delete(AJXP_CACHE_SERVICE_NS_NODES, AbstractCacheDriver::computeIdForNode($node, "stat"));
+ $cacheDriver->delete(AJXP_CACHE_SERVICE_NS_NODES, AbstractCacheDriver::computeIdForNode($node, "stat"));
// Clear parent listing
if($node->getParent() !== null){
- CacheService::delete(AJXP_CACHE_SERVICE_NS_NODES, AbstractCacheDriver::computeIdForNode($node->getParent(), "list"));
+ $cacheDriver->delete(AJXP_CACHE_SERVICE_NS_NODES, AbstractCacheDriver::computeIdForNode($node->getParent(), "list"));
}
}else {
- $cacheDriver = ConfService::getCacheDriverImpl();
- $cacheDriver->deleteKeyStartingWith(AJXP_CACHE_SERVICE_NS_NODES, $this->computeId($node, true));
- $cacheDriver->deleteKeyStartingWith(AJXP_CACHE_SERVICE_NS_NODES, $this->computeId($node, false));
+ // Delete node data and all its children
$cacheDriver->deleteKeyStartingWith(AJXP_CACHE_SERVICE_NS_NODES, AbstractCacheDriver::computeIdForNode($node, "stat"));
if($node->getParent() !== null){
$cacheDriver->deleteKeyStartingWith(AJXP_CACHE_SERVICE_NS_NODES, AbstractCacheDriver::computeIdForNode($node->getParent(), "list"));
@@ -176,7 +201,11 @@ protected function computeId($node, $details){
return AbstractCacheDriver::computeIdForNode($node, "node.info", $details?"all":"short");
}
- public function exposeCacheStats($actionName, $httpVars, $fileVars){
+ /**
+ * @param ServerRequestInterface $requestInterface
+ * @param ResponseInterface $responseInterface
+ */
+ public function exposeCacheStats(ServerRequestInterface $requestInterface, ResponseInterface &$responseInterface){
$cImpl = $this->getImplementation();
$result = [];
@@ -188,21 +217,23 @@ public function exposeCacheStats($actionName, $httpVars, $fileVars){
$result[] = $data;
}
}
- \Pydio\Core\Controller\HTMLWriter::charsetHeader("application/json");
- echo json_encode($result);
+ $responseInterface = new JsonResponse($result);
}
- public function clearCacheByNS($actionName, $httpVars, $fileVars){
+ /**
+ * @param ServerRequestInterface $requestInterface
+ * @param ResponseInterface $responseInterface
+ */
+ public function clearCacheByNS(ServerRequestInterface $requestInterface, ResponseInterface &$responseInterface){
- $ns = \Pydio\Core\Utils\Utils::sanitize($httpVars["namespace"], AJXP_SANITIZE_ALPHANUM);
+ $ns = Utils::sanitize($requestInterface->getParsedBody()["namespace"], AJXP_SANITIZE_ALPHANUM);
if($ns == AJXP_CACHE_SERVICE_NS_SHARED){
ConfService::clearAllCaches();
}else{
CacheService::deleteAll($ns);
}
- HTMLWriter::charsetHeader("text/json");
- echo json_encode(["result"=>"ok"]);
+ $responseInterface = new JsonResponse(["result"=>"ok"]);
}
@@ -30,7 +30,8 @@
<serverCallback methodName="cacheNodeInfo" hookName="node.info.end"/>
<serverCallback methodName="clearNodeInfoCache" hookName="node.change" defer="true"/>
<serverCallback methodName="clearNodeInfoCache" hookName="node.meta_change" defer="true"/>
- <serverCallback methodName="clearWorkspaceNodeInfos" hookName="workspace.after_update" defer="true"/>
+ <serverCallback methodName="onWorkspaceUpdate" hookName="workspace.after_update" defer="true"/>
+ <serverCallback methodName="onWorkspaceDelete" hookName="workspace.after_delete" defer="true"/>
</hooks>
</registry_contributions>
</ajxp_plugin>

0 comments on commit 2a4101b

Please sign in to comment.