Permalink
Browse files

When using APC as cache driver and when in CLI context, we need to fo…

…rward delete instructions to server. Group all instructions inside a unique http call at the end of the process.
  • Loading branch information...
1 parent 0067484 commit 9dd8d3c417bb2bb5bb002cc877a60f5c95ece2eb @cdujeu cdujeu committed Jun 25, 2016
@@ -26,11 +26,17 @@
define('AJXP_CACHE_SERVICE_NS_NODES', 'nodes');
use Doctrine\Common\Cache;
+use Psr\Http\Message\ResponseInterface;
use Pydio\Access\Core\Model\AJXP_Node;
+use Pydio\Cache\Doctrine\Ext\PydioApcuCache;
use Pydio\Core\PluginFramework\Plugin;
use Pydio\Cache\Doctrine\Ext\PatternClearableCache;
+use Pydio\Core\Services\ConfService;
+use GuzzleHttp\Client;
+use Pydio\Core\Utils\ApplicationState;
+use Pydio\Log\Core\Logger;
/**
* @package AjaXplorer_Plugins
@@ -55,6 +61,16 @@
*/
protected $namespacedCaches = array();
+ /**
+ * Keep a pointer to an http client if necessary
+ * @var Client
+ */
+ protected $httpClient;
+
+ /**
+ * @var array
+ */
+ private $httpDeletion = [];
/**
* @param string $namespace
@@ -105,29 +121,6 @@ public static function computeFullRepositoryId($repositoryId, $cacheType){
}
/**
- * @param string $namespace
- * @return bool
- */
- public function supportsPatternDelete($namespace)
- {
- $cacheDriver = $this->getCacheDriver($namespace);
- return $cacheDriver instanceof PatternClearableCache;
- }
-
- /**
- * @param string $namespace
- * @param string $id
- * @return bool
- */
- public function deleteKeyStartingWith($namespace, $id){
- $cacheDriver = $this->getCacheDriver($namespace);
- if(!($cacheDriver instanceof PatternClearableCache)){
- return false;
- }
- return $cacheDriver->deleteKeysStartingWith($id);
- }
-
- /**
* Fetches an entry from the cache.
*
* @param $namespace
@@ -194,11 +187,17 @@ public function save($namespace, $id, $data, $lifeTime = 0){
* @return bool TRUE if the entry was successfully deleted, FALSE otherwise.
*/
public function delete($namespace, $id){
+
$cacheDriver = $this->getCacheDriver($namespace);
+ if($this->requiresHttpForwarding($cacheDriver)){
+ $this->httpDeletion[$namespace.$id.'key'] = ["namespace"=>$namespace, "key" => $id];
+ return true;
+ }
if (isset($cacheDriver) && $cacheDriver->contains($id)) {
- $result = $cacheDriver->delete($id);
- return $result;
+ Logger::debug("CacheDriver::Http", "Clear Key ".$id, ["namespace" => $namespace]);
+ $result = $cacheDriver->delete($id);
+ return $result;
}
return false;
@@ -212,23 +211,103 @@ public function delete($namespace, $id){
*
*/
public function deleteAll($namespace){
+
$cacheDriver = $this->getCacheDriver($namespace);
+ if($this->requiresHttpForwarding($cacheDriver)){
+ $this->httpDeletion[$namespace.'all'] = ["namespace"=>$namespace, "all" => "true"];
+ return true;
+ }
if (isset($cacheDriver)) {
- $result = $cacheDriver->deleteAll();
- return $result;
+ Logger::debug("CacheDriver::Http", "Clear All", ["namespace" => $namespace]);
+ $result = $cacheDriver->deleteAll();
+ return $result;
}
return false;
}
+ /**
+ * @param string $namespace
+ * @return bool
+ */
+ public function supportsPatternDelete($namespace)
+ {
+ $cacheDriver = $this->getCacheDriver($namespace);
+ return $cacheDriver instanceof PatternClearableCache;
+ }
+
+ /**
+ * @param string $namespace
+ * @param string $id
+ * @return bool
+ */
+ public function deleteKeyStartingWith($namespace, $id){
+
+ $cacheDriver = $this->getCacheDriver($namespace);
+ if($this->requiresHttpForwarding($cacheDriver)){
+ $this->httpDeletion[$namespace.$id.'pattern'] = ["namespace"=>$namespace, "pattern" => $id];
+ return true;
+ }
+
+ if(!($cacheDriver instanceof PatternClearableCache)){
+ return false;
+ }
+ Logger::debug("CacheDriver::Http", "Clear Pattern ".$id, ["namespace" => $namespace]);
+ return $cacheDriver->deleteKeysStartingWith($id);
+ }
+
+
+ /**
+ * @return array
+ */
public function listNamespaces(){
return [AJXP_CACHE_SERVICE_NS_SHARED, AJXP_CACHE_SERVICE_NS_NODES];
}
+ /**
+ * @param $namespace
+ * @return array|null
+ */
public function getStats($namespace){
$cacheDriver = $this->getCacheDriver($namespace);
return $cacheDriver->getStats();
}
+ /**
+ * @param CacheProvider
+ * @return bool
+ */
+ protected function requiresHttpForwarding($cacheDriver){
+ if(!empty($cacheDriver) && $cacheDriver instanceof PydioApcuCache && ConfService::currentContextIsCommandLine()){
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * @return Client
+ */
+ protected function getHttpClient(){
+ if(!isSet($this->httpClient)){
+ $this->httpClient = new Client([
+ 'base_url' => ApplicationState::detectServerURL(true)
+ ]);
+ }
+ return $this->httpClient;
+ }
+
+ public function __destruct()
+ {
+ if(count($this->httpDeletion)){
+ Logger::debug("CacheDriver::CLI", "Sending cache clear to http", $this->httpDeletion);
+ $this->getHttpClient()->post('/?get_action=clear_cache_key', [
+ 'body' => [
+ 'data' => json_encode($this->httpDeletion)
+ ]
+ ]);
+
+ }
+ }
+
}
@@ -33,6 +33,7 @@
use Pydio\Access\Core\Model\AJXP_Node;
use Pydio\Core\Utils\Vars\InputFilter;
+use Pydio\Log\Core\Logger;
use Zend\Diactoros\Response\JsonResponse;
defined('AJXP_EXEC') or die( 'Access not allowed');
@@ -238,5 +239,33 @@ public function clearCacheByNS(ServerRequestInterface $requestInterface, Respons
}
+ /**
+ * Service to clear a cache key or a pattern
+ * @param ServerRequestInterface $requestInterface
+ * @param ResponseInterface $responseInterface
+ */
+ public function clearCacheKey(ServerRequestInterface $requestInterface, ResponseInterface &$responseInterface){
+ $cacheDriver = ConfService::getCacheDriverImpl();
+ if($cacheDriver === null) {
+ $responseInterface = new JsonResponse(["result" => "NOCACHEFOUND"]);
+ return;
+ }
+ $params = $requestInterface->getParsedBody();
+ $data = json_decode($params["data"], true);
+ foreach($data as $key => $params){
+ $ns = $params['namespace'];
+ if(isSet($params["key"])){
+ Logger::info("CoreCacheLoader", "Clear Key ".$params["key"], $params);
+ $cacheDriver->delete($ns, $params["key"]);
+ }else if(isSet($params["pattern"])){
+ Logger::info("CoreCacheLoader", "Clear Pattern ".$params["pattern"], $params);
+ $cacheDriver->deleteKeyStartingWith($ns, $params["pattern"]);
+ }else if(isSet($params["all"])) {
+ Logger::info("CoreCacheLoader", "Clear All ", $params);
+ $cacheDriver->deleteAll($ns);
+ }
+ }
+ $responseInterface = new JsonResponse(["result" => "SUCCESS"]);
+ }
}
@@ -24,6 +24,11 @@
<serverCallback methodName="clearCacheByNS" restParams="/namespace"/>
</processing>
</action>
+ <action name="clear_cache_key" skipSecureToken="true">
+ <processing>
+ <serverCallback methodName="clearCacheKey" restParams="/namespace"/>
+ </processing>
+ </action>
</actions>
<hooks>
<serverCallback methodName="loadNodeInfoFromCache" hookName="node.info.start"/>

0 comments on commit 9dd8d3c

Please sign in to comment.