Permalink
Browse files

Change cache invalidation method, by timestamping cached data and che…

…cking a given key against other data stamps. To be tested extensively.
  • Loading branch information...
1 parent 6d429a9 commit 9a6a77700eb60477d9fe1945075eb7584c0ea872 @cdujeu cdujeu committed Sep 22, 2016
@@ -281,4 +281,10 @@ public function updatePersonalRole(AJXP_Role $role);
* @throws \Exception
*/
public function reloadRolesIfRequired();
+
+ /**
+ * @return array
+ */
+ public function getRolesKeys();
+
}
@@ -430,7 +430,10 @@ public function getFilteredXMLRegistry($extendedVersion = true, $clone = false,
{
if ($useCache) {
$cacheKey = $this->getRegistryCacheKey($extendedVersion);
- $cachedXml = CacheService::fetch(AJXP_CACHE_SERVICE_NS_SHARED, $cacheKey);
+ $tStamps = [];
+ if($this->context->hasUser()) $tStamps[] = "pydio:user:".$this->context->getUser()->getId();
+ if($this->context->hasRepository()) $tStamps[] = "pydio:repository:".$this->context->getRepositoryId();
+ $cachedXml = CacheService::fetchWithTimestamps(AJXP_CACHE_SERVICE_NS_SHARED, $cacheKey, $tStamps);
if ($cachedXml !== false) {
$registry = new \DOMDocument("1.0", "utf-8");
$registry->loadXML($cachedXml);
@@ -452,7 +455,7 @@ public function getFilteredXMLRegistry($extendedVersion = true, $clone = false,
}
if ($useCache && isSet($cacheKey)) {
- CacheService::save(AJXP_CACHE_SERVICE_NS_SHARED, $cacheKey, $registry->saveXML());
+ CacheService::saveWithTimestamp(AJXP_CACHE_SERVICE_NS_SHARED, $cacheKey, $registry->saveXML());
}
if ($clone) {
@@ -56,6 +56,7 @@ public static function save($namespace, $id, $object, $timelimit = 0) {
$cacheDriver = ConfService::getCacheDriverImpl();
if ($cacheDriver) {
+ //if($namespace === AJXP_CACHE_SERVICE_NS_SHARED) error_log("Saving data for $id");
return $cacheDriver->save($namespace, $id, $object, $timelimit);
}
@@ -65,13 +66,35 @@ public static function save($namespace, $id, $object, $timelimit = 0) {
/**
* @param $namespace
* @param $id
+ * @param $object
+ * @param int $timelimit
+ * @return bool
+ */
+ public static function saveWithTimestamp($namespace, $id, $object, $timelimit = 0){
+ $cacheDriver = ConfService::getCacheDriverImpl();
+
+ if ($cacheDriver) {
+ //if($namespace === AJXP_CACHE_SERVICE_NS_SHARED) error_log("Saving data for $id with timestamp");
+ return $cacheDriver->saveWithTimestamp($namespace, $id, $object, $timelimit);
+ }
+
+ return false;
+
+ }
+
+ /**
+ * @param $namespace
+ * @param $id
* @return bool|mixed
*/
public static function fetch($namespace, $id) {
$cacheDriver = ConfService::getCacheDriverImpl();
if ($cacheDriver) {
$data = $cacheDriver->fetch($namespace, $id);
+ if($data !== false && $namespace === AJXP_CACHE_SERVICE_NS_SHARED){
+ //error_log("Found data for $id");
+ }
return $data;
}
@@ -80,6 +103,42 @@ public static function fetch($namespace, $id) {
/**
* @param $namespace
+ * @param array $ids
+ * @return bool|mixed
+ */
+ public static function fetchMultiple($namespace, $ids) {
+ $cacheDriver = ConfService::getCacheDriverImpl();
+
+ if ($cacheDriver) {
+ return $cacheDriver->fetchMultiple($namespace, $ids);
+ }
+
+ return false;
+ }
+
+ /**
+ * @param $namespace
+ * @param $id
+ * @param array $idsToCheck
+ * @return bool|false|mixed
+ */
+ public static function fetchWithTimestamps($namespace, $id, $idsToCheck){
+ $cacheDriver = ConfService::getCacheDriverImpl();
+
+ if ($cacheDriver) {
+ $data = $cacheDriver->fetchWithTimestamps($namespace, $id, $idsToCheck);
+ if($data !== false && $namespace === AJXP_CACHE_SERVICE_NS_SHARED){
+ //error_log("Found data for $id after checking timestamps for ".implode(",", $idsToCheck));
+ }
+ return $data;
+ }
+
+ return false;
+
+ }
+
+ /**
+ * @param $namespace
* @param $id
* @return bool
*/
@@ -360,23 +360,23 @@ private function getRepositoryByIdInst($repoId)
if (isSet($this->cache["REPOSITORIES"]) && isSet($this->cache["REPOSITORIES"][$repoId])) {
return $this->cache["REPOSITORIES"][$repoId];
}
- $test = CacheService::fetch(AJXP_CACHE_SERVICE_NS_SHARED, "repository:" . $repoId);
+ $test = CacheService::fetch(AJXP_CACHE_SERVICE_NS_SHARED, "pydio:repository:" . $repoId);
if($test !== false){
$this->cache["REPOSITORIES"][$repoId] = $test;
return $test;
}
$test = ConfService::getConfStorageImpl()->getRepositoryById($repoId);
if($test != null) {
$this->cache["REPOSITORIES"][$repoId] = $test;
- CacheService::save(AJXP_CACHE_SERVICE_NS_SHARED, "repository:" . $repoId, $test);
+ CacheService::saveWithTimestamp(AJXP_CACHE_SERVICE_NS_SHARED, "pydio:repository:" . $repoId, $test);
return $test;
}
// Finally try to search in default repositories
$statics = self::getStaticRepositories();
if (isSet($statics[$repoId])) {
$repo = $statics[$repoId];
$this->cache["REPOSITORIES"][$repoId] = $test;
- CacheService::save(AJXP_CACHE_SERVICE_NS_SHARED, "repository:" . $repoId, $repo);
+ CacheService::saveWithTimestamp(AJXP_CACHE_SERVICE_NS_SHARED, "pydio:repository:" . $repoId, $repo);
return $repo;
}
$hookedRepo = null;
@@ -440,9 +440,7 @@ private function addRepositoryInst($oRepository)
}
Controller::applyHook("workspace.after_create", array(Context::fromGlobalServices(), $oRepository));
Logger::info(__CLASS__,"Create Repository", array("repo_name"=>$oRepository->getDisplay()));
- CacheService::save(AJXP_CACHE_SERVICE_NS_SHARED, "repository:".$oRepository->getId(), $oRepository);
- // TODO ?
- //$this->invalidateLoadedRepositories();
+ CacheService::saveWithTimestamp(AJXP_CACHE_SERVICE_NS_SHARED, "pydio:repository:".$oRepository->getId(), $oRepository);
return null;
}
@@ -479,9 +477,7 @@ private function replaceRepositoryInst($oldId, $oRepositoryObject)
}
Controller::applyHook("workspace.after_update", array(Context::fromGlobalServices(), $oRepositoryObject));
Logger::info(__CLASS__,"Edit Repository", array("repo_name"=>$oRepositoryObject->getDisplay()));
- // TODO ?
- //$this->invalidateLoadedRepositories();
- CacheService::save(AJXP_CACHE_SERVICE_NS_SHARED, "repository:" . $oRepositoryObject->getId(), $oRepositoryObject);
+ CacheService::saveWithTimestamp(AJXP_CACHE_SERVICE_NS_SHARED, "pydio:repository:" . $oRepositoryObject->getId(), $oRepositoryObject);
return 0;
}
@@ -508,9 +504,7 @@ private function deleteRepositoryInst($repoId)
}
Controller::applyHook("workspace.after_delete", array(Context::fromGlobalServices(), $repoId));
Logger::info(__CLASS__,"Delete Repository", array("repo_id"=>$repoId));
- // TODO ?
- //$this->invalidateLoadedRepositories();
- CacheService::delete(AJXP_CACHE_SERVICE_NS_SHARED, "repository:".$repoId);
+ CacheService::delete(AJXP_CACHE_SERVICE_NS_SHARED, "pydio:repository:".$repoId);
return 0;
}
@@ -142,7 +142,7 @@ public static function getOrCreateRole($roleId, $groupPath = "/")
public static function updateRole($roleObject, $userObject = null)
{
ConfService::getConfStorageImpl()->updateRole($roleObject, $userObject);
- //CacheService::deleteAll(AJXP_CACHE_SERVICE_NS_SHARED);
+ CacheService::saveWithTimestamp(AJXP_CACHE_SERVICE_NS_SHARED, "pydio:role:".$roleObject->getId(), $roleObject);
ConfService::getInstance()->invalidateLoadedRepositories();
}
@@ -155,7 +155,7 @@ public static function updateRole($roleObject, $userObject = null)
public static function deleteRole($roleId)
{
ConfService::getConfStorageImpl()->deleteRole($roleId);
- //CacheService::deleteAll(AJXP_CACHE_SERVICE_NS_SHARED);
+ CacheService::delete(AJXP_CACHE_SERVICE_NS_SHARED, "pydio:role:".$roleId);
ConfService::getInstance()->invalidateLoadedRepositories();
}
@@ -230,6 +230,26 @@ public static function getRolesList($roleIds = array(), $excludeReserved = false
if (self::$useCache && !count($roleIds) && $excludeReserved == true && self::$rolesCache != null) {
return self::$rolesCache;
}
+ $searches = array_map(function($k){return "pydio:role:".$k;}, $roleIds);
+ $fetches = CacheService::fetchMultiple(AJXP_CACHE_SERVICE_NS_SHARED, $searches);
+ $missing = [];
+ if(count($fetches)){
+ $found = [];
+ foreach($searches as $cacheKey){
+ $okKey = preg_replace('/^pydio:role:/', "", $cacheKey);
+ if(isSet($fetches[$cacheKey]) && $fetches[$cacheKey] instanceof AJXP_Role){
+ $found[$okKey] = $fetches[$cacheKey];
+ }else{
+ $missing[] = $okKey;
+ }
+ }
+ if(!count($missing)){
+ return $found;
+ }else{
+ $roleIds = $missing;
+ }
+ }
+
$confDriver = ConfService::getConfStorageImpl();
$roles = $confDriver->listRoles($roleIds, $excludeReserved);
$repoList = null;
@@ -241,6 +261,13 @@ public static function getRolesList($roleIds = array(), $excludeReserved = false
$roles[$roleId] = $newRole;
self::updateRole($newRole);
}
+ if(count($roleIds)){
+ CacheService::saveWithTimestamp(AJXP_CACHE_SERVICE_NS_SHARED, "pydio:role:".$roleId, $roleObject);
+ }
+ }
+ if(isSet($found) && count($found)){
+ // Add the ones loaded from cache
+ $roles = array_merge($roles, $found);
}
if (self::$useCache && !count($roleIds) && $excludeReserved == true) {
self::$rolesCache = $roles;
@@ -82,14 +82,19 @@ public static function getUserById($userId, $checkExists = true){
return $self->usersCache[$userId];
}
// Try to get from cache
- $test = CacheService::fetch("shared", "pydio:user:" . $userId);
+ $test = CacheService::fetch(AJXP_CACHE_SERVICE_NS_SHARED, "pydio:user:" . $userId);
if($test !== false && $test instanceof UserInterface){
- if($test->getPersonalRole() === null){
- $test->updatePersonalRole($test->getRoles()["AJXP_USR_/".$userId]);
+ // Second check : if roles were updated in cache
+ $roleCacheIds = array_map(function($k){ return "pydio:role:".$k; }, $test->getRolesKeys());
+ $test = CacheService::fetchWithTimestamps(AJXP_CACHE_SERVICE_NS_SHARED, "pydio:user:".$userId, $roleCacheIds);
+ if($test !== false){
+ if($test->getPersonalRole() === null){
+ $test->updatePersonalRole($test->getRoles()["AJXP_USR_/".$userId]);
+ }
+ $test->recomputeMergedRole();
+ $self->usersCache[$userId] = $test;
+ return $test;
}
- $test->recomputeMergedRole();
- $self->usersCache[$userId] = $test;
- return $test;
}
if($checkExists && !self::userExists($userId)){
throw new UserNotFoundException($userId);
@@ -100,20 +105,25 @@ public static function getUserById($userId, $checkExists = true){
// Save in memory
$self->usersCache[$userId] = $userObject;
// Save in cache
- CacheService::save("shared", "pydio:user:" . $userId, $userObject);
+ CacheService::saveWithTimestamp(AJXP_CACHE_SERVICE_NS_SHARED, "pydio:user:" . $userId, $userObject);
}
return $userObject;
}
/**
* @param $userObject UserInterface
+ * @param string $scope
*/
- public static function updateUser($userObject){
+ public static function updateUser($userObject, $scope = "user"){
$self = self::instance();
$userId = $userObject->getId();
$self->usersCache[$userId] = $userObject;
- CacheService::save("shared", "pydio:user:" . $userId, $userObject);
+ if($scope === "user"){
+ CacheService::save(AJXP_CACHE_SERVICE_NS_SHARED, "pydio:user:" . $userId, $userObject);
+ }else{
+ CacheService::saveWithTimestamp(AJXP_CACHE_SERVICE_NS_SHARED, "pydio:user:" . $userId, $userObject);
+ }
}
/**
@@ -206,7 +216,6 @@ public static function invalidateCache(){
self::instance()->repositoriesCache = [];
self::instance()->usersCache = [];
- CacheService::deleteAll(AJXP_CACHE_SERVICE_NS_SHARED);
SessionService::invalidateLoadedRepositories();
}
Oops, something went wrong.

0 comments on commit 9a6a777

Please sign in to comment.