suite implémentation cache
This commit is contained in:
		
							parent
							
								
									ec0c0eef3e
								
							
						
					
					
						commit
						c80d99e829
					
				
							
								
								
									
										17
									
								
								src/file/cache/CacheData.php
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										17
									
								
								src/file/cache/CacheData.php
									
									
									
									
										vendored
									
									
								
							| @ -12,10 +12,9 @@ class CacheData { | ||||
|   /** @var callable une fonction permettant de calculer la donnée */ | ||||
|   const COMPUTE = null; | ||||
| 
 | ||||
|   function __construct(?array $params=null) { | ||||
|     $this->name = $params["name"] ?? static::NAME; | ||||
|     $this->name ??= bin2hex(random_bytes(8)); | ||||
|     $this->compute = func::withn($params["compute"] ?? static::COMPUTE); | ||||
|   function __construct(?string $name=null, $compute=null) { | ||||
|     $this->name = $name ?? static::NAME ?? bin2hex(random_bytes(8)); | ||||
|     $this->compute = func::withn($compute ?? static::COMPUTE); | ||||
|   } | ||||
| 
 | ||||
|   protected string $name; | ||||
| @ -27,9 +26,12 @@ class CacheData { | ||||
|     return $compute !== null? $compute->invoke(): null; | ||||
|   } | ||||
| 
 | ||||
|   function getName() : string { | ||||
|     return $this->name; | ||||
|   } | ||||
| 
 | ||||
|   /** obtenir la donnée, en l'itérant au préalable si elle est traversable */ | ||||
|   function get(?string &$name, $compute=null) { | ||||
|     $name = $this->name; | ||||
|   function get($compute=null) { | ||||
|     $this->compute ??= func::withn($compute); | ||||
|     $data = $this->compute(); | ||||
|     if ($data instanceof Traversable) { | ||||
| @ -39,8 +41,7 @@ class CacheData { | ||||
|   } | ||||
| 
 | ||||
|   /** obtenir un itérateur sur la donnée ou null s'il n'y a pas de données */ | ||||
|   function all(?string &$name, $compute=null): ?iterable { | ||||
|     $name = $this->name; | ||||
|   function all($compute=null): ?iterable { | ||||
|     $this->compute ??= func::withn($compute); | ||||
|     $data = $this->compute(); | ||||
|     if ($data !== null && !is_iterable($data)) $data = [$data]; | ||||
|  | ||||
							
								
								
									
										88
									
								
								src/file/cache/CacheFile.php
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										88
									
								
								src/file/cache/CacheFile.php
									
									
									
									
										vendored
									
									
								
							| @ -1,6 +1,8 @@ | ||||
| <?php | ||||
| namespace nulib\file\cache; | ||||
| 
 | ||||
| use Exception; | ||||
| use nulib\file; | ||||
| use nulib\file\SharedFile; | ||||
| use nulib\os\path; | ||||
| use nulib\php\time\DateTime; | ||||
| @ -23,7 +25,6 @@ class CacheFile extends SharedFile { | ||||
|     $this->duration = Delay::with($params["duration"] ?? static::DURATION); | ||||
|     $this->overrideDuration = $params["override_duration"] ?? false; | ||||
|     $this->cacheNull = $params["cache_null"] ?? false; | ||||
|     $this->datafiles = []; | ||||
|     parent::__construct($file); | ||||
|   } | ||||
| 
 | ||||
| @ -39,8 +40,6 @@ class CacheFile extends SharedFile { | ||||
| 
 | ||||
|   protected bool $cacheNull; | ||||
| 
 | ||||
|   protected array $datafiles; | ||||
| 
 | ||||
|   /** | ||||
|    * vérifier si le fichier est valide. s'il est invalide, il faut le recréer. | ||||
|    * | ||||
| @ -52,7 +51,7 @@ class CacheFile extends SharedFile { | ||||
|   } | ||||
| 
 | ||||
|   /** charger les données. le fichier a déjà été verrouillé en lecture */ | ||||
|   protected function loadData(): ?array { | ||||
|   protected function loadMetadata(): ?array { | ||||
|     $this->rewind(); | ||||
|     [ | ||||
|       "start" => $start, | ||||
| @ -74,7 +73,7 @@ class CacheFile extends SharedFile { | ||||
|     if ($this->isValid()) { | ||||
|       /** @var Delay $duration */ | ||||
|       ["duration" => $duration, | ||||
|       ] = $this->loadData(); | ||||
|       ] = $this->loadMetadata(); | ||||
|       $expired = $duration->isElapsed(); | ||||
|     } else { | ||||
|       $expired = false; | ||||
| @ -84,7 +83,7 @@ class CacheFile extends SharedFile { | ||||
|   } | ||||
| 
 | ||||
|   /** sauvegarder les données. le fichier a déjà été verrouillé en écriture */ | ||||
|   protected function saveData(?DateTime $start=null, ?Delay $duration=null): void { | ||||
|   protected function saveMetadata(?DateTime $start, ?Delay $duration, array $datafiles): void { | ||||
|     $duration ??= $this->duration; | ||||
|     if ($start === null) { | ||||
|       $start = new DateTime(); | ||||
| @ -94,15 +93,76 @@ class CacheFile extends SharedFile { | ||||
|     $this->serialize([ | ||||
|       "start" => $start, | ||||
|       "duration" => $duration, | ||||
|       "datafiles" => $this->datafiles, | ||||
|       "datafiles" => $datafiles, | ||||
|     ], false, true); | ||||
|   } | ||||
| 
 | ||||
|   function loadData(string $datafile) { | ||||
|     $datafile = path::join($this->basedir, $datafile); | ||||
|     return file::reader($datafile)->unserialize(); | ||||
|   } | ||||
| 
 | ||||
|   function saveData(string $datafile, $data): void { | ||||
|     $datafile = path::join($this->basedir, $datafile); | ||||
|     file::writer($datafile)->serialize($data); | ||||
|   } | ||||
| 
 | ||||
|   protected function unlinkDatafile(string $datafile): void { | ||||
|     @unlink(path::join($this->basedir, $datafile)); | ||||
|   } | ||||
| 
 | ||||
|   protected function unlinkFiles(?array $datafiles): void { | ||||
|     if ($datafiles === null && $this->isValid()) { | ||||
|       $this->lockRead(); | ||||
|       try { | ||||
|         ["datafiles" => $datafiles | ||||
|         ] = $this->loadMetadata(); | ||||
|       } finally { | ||||
|         $this->unlock(); | ||||
|       } | ||||
|     } | ||||
|     @unlink($this->file); | ||||
|     if ($datafiles !== null) { | ||||
|       foreach ($datafiles as $datafile) { | ||||
|         $this->unlinkDatafile($datafile); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   /** tester si $value peut être mis en cache */ | ||||
|   function shouldCache($value): bool { | ||||
|   protected function shouldCache($value): bool { | ||||
|     return $this->cacheNull || $value !== null; | ||||
|   } | ||||
| 
 | ||||
|   function get(?CacheData $data=null, bool $noCache=false) { | ||||
|     $this->lockRead(); | ||||
|     try { | ||||
|       $datafile = $data->getName(); | ||||
|       $datafile = "{$this->basename}.data.{$datafile}.cache"; | ||||
|       #XXX mettre à jour datafiles dans metadata
 | ||||
|       if ($this->shouldUpdate($noCache)) { | ||||
|         $this->lockWrite(); | ||||
|         try { | ||||
|           $data = $data->get(); | ||||
|           if ($this->shouldCache($data)) { | ||||
|             $this->saveData($datafile, $data); | ||||
|           } else { | ||||
|             # ne pas garder le fichier s'il ne faut pas mettre en cache
 | ||||
|             $this->unlinkDatafile($datafile); | ||||
|           } | ||||
|         } catch (Exception $e) { | ||||
|           $this->unlinkDatafile($datafile); | ||||
|           throw $e; | ||||
|         } | ||||
|       } else { | ||||
|         $data = $this->loadData($datafile); | ||||
|       } | ||||
|       return $data; | ||||
|     } finally { | ||||
|       $this->unlock(); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   /** obtenir les informations sur le fichier */ | ||||
|   function getInfos(): array { | ||||
|     $this->lockRead(); | ||||
| @ -118,7 +178,7 @@ class CacheFile extends SharedFile { | ||||
|         "start" => $start, | ||||
|         "duration" => $duration, | ||||
|         "datafiles" => $datafiles, | ||||
|       ] = $this->loadData(); | ||||
|       ] = $this->loadMetadata(); | ||||
|       return [ | ||||
|         "valid" => true, | ||||
|         "size" => $this->getSize(), | ||||
| @ -148,10 +208,10 @@ class CacheFile extends SharedFile { | ||||
|       [ | ||||
|         "start" => $start, | ||||
|         "duration" => $duration, | ||||
|       ] = $this->loadData(); | ||||
|       ] = $this->loadMetadata(); | ||||
|       if ($action < 0) $duration->subDuration($nduration); | ||||
|       elseif ($action > 0) $duration->addDuration($nduration); | ||||
|       $this->saveData($start, $duration); | ||||
|       $this->saveMetadata($start, $duration); | ||||
|     } finally { | ||||
|       $this->unlock(); | ||||
|     } | ||||
| @ -163,11 +223,7 @@ class CacheFile extends SharedFile { | ||||
|     try { | ||||
|       if ($force || $this->shouldUpdate()) { | ||||
|         $this->lockWrite(); | ||||
|         @unlink($this->file); | ||||
|         $basedir = $this->basedir; | ||||
|         foreach ($this->datafiles as $datafile) { | ||||
|           @unlink(path::join($basedir, $datafile)); | ||||
|         } | ||||
|         $this->unlinkFiles(); | ||||
|         return true; | ||||
|       } | ||||
|     } finally { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user