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