FileCachedValue utilise Delay
This commit is contained in:
		
							parent
							
								
									cf89396467
								
							
						
					
					
						commit
						4494c8ecc3
					
				@ -44,7 +44,7 @@ Application::run(new class extends Application {
 | 
			
		||||
 | 
			
		||||
  protected $args;
 | 
			
		||||
 | 
			
		||||
  function setActionUpdate(int $action, int $updateDuration): void {
 | 
			
		||||
  function setActionUpdate(int $action, $updateDuration): void {
 | 
			
		||||
    $this->action = self::ACTION_UPDATE;
 | 
			
		||||
    switch ($action) {
 | 
			
		||||
    case self::ACTION_UPDATE_SUB: $this->updateAction = -1; break;
 | 
			
		||||
@ -81,7 +81,7 @@ Application::run(new class extends Application {
 | 
			
		||||
      case self::ACTION_READ:
 | 
			
		||||
        if ($showSection) msg::section($file);
 | 
			
		||||
        $cache = new CacheFile($file, [
 | 
			
		||||
          "duration" => PHP_INT_MAX,
 | 
			
		||||
          "duration" => "INF",
 | 
			
		||||
          "override_duration" => true,
 | 
			
		||||
        ]);
 | 
			
		||||
        yaml::dump($cache->get());
 | 
			
		||||
 | 
			
		||||
@ -7,15 +7,14 @@ use Exception;
 | 
			
		||||
use Generator;
 | 
			
		||||
use nur\A;
 | 
			
		||||
use nur\b\coll\TBaseArray;
 | 
			
		||||
use nur\b\date\Date;
 | 
			
		||||
use nur\b\date\Datetime;
 | 
			
		||||
use nur\b\IllegalAccessException;
 | 
			
		||||
use nur\b\params\Parametrable;
 | 
			
		||||
use nur\b\params\Tparametrable;
 | 
			
		||||
use nur\data\types\Tmd;
 | 
			
		||||
use nur\file;
 | 
			
		||||
use nur\os;
 | 
			
		||||
use nur\ref\ref_cache;
 | 
			
		||||
use nur\sery\php\time\DateTime;
 | 
			
		||||
use nur\sery\php\time\Delay;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class FileCachedValue: un fichier utilisé pour mettre en cache certaines
 | 
			
		||||
@ -28,8 +27,8 @@ abstract class FileCachedValue extends Parametrable implements ArrayAccess, Coun
 | 
			
		||||
  /** @var string chemin vers le fichier cache par défaut */
 | 
			
		||||
  const FILE = null;
 | 
			
		||||
 | 
			
		||||
  /** @var int durée de vie par défaut du cache en secondes */
 | 
			
		||||
  const DURATION = 8 * ref_cache::HOUR;
 | 
			
		||||
  /** @var int durée de vie par défaut du cache */
 | 
			
		||||
  const DURATION = "1D"; // jusqu'au lendemain
 | 
			
		||||
 | 
			
		||||
  /** @var bool faut-il mettre en cache la valeur nulle? */
 | 
			
		||||
  const CACHE_NULL = false;
 | 
			
		||||
@ -50,7 +49,7 @@ abstract class FileCachedValue extends Parametrable implements ArrayAccess, Coun
 | 
			
		||||
 | 
			
		||||
  const PARAMETRABLE_PARAMS_SCHEMA = [
 | 
			
		||||
    "file" => ["?string", null, "chemin vers le fichier"],
 | 
			
		||||
    "duration" => ["int", null, "durée de vie du cache en secondes"],
 | 
			
		||||
    "duration" => [Delay::class, null, "durée de vie du cache"],
 | 
			
		||||
    "override_duration" => ["bool", false, "faut-il ignorer la duration inscrite dans le fichier et prendre la valeur locale?"],
 | 
			
		||||
    "cache_null" => ["bool", false, "faut-il mettre en cache la valeur null?"],
 | 
			
		||||
    "data" => ["array", null, "données supplémentaires"]
 | 
			
		||||
@ -67,7 +66,7 @@ abstract class FileCachedValue extends Parametrable implements ArrayAccess, Coun
 | 
			
		||||
    return $cacheFile;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** @var int */
 | 
			
		||||
  /** @var Delay */
 | 
			
		||||
  protected $ppDuration;
 | 
			
		||||
 | 
			
		||||
  /** @var bool */
 | 
			
		||||
@ -94,8 +93,8 @@ abstract class FileCachedValue extends Parametrable implements ArrayAccess, Coun
 | 
			
		||||
    $outf = file::open($file, "wb");
 | 
			
		||||
    try {
 | 
			
		||||
      $contents = $this->serialize($data);
 | 
			
		||||
      $tstart = time();
 | 
			
		||||
      $duration = $this->ppDuration;
 | 
			
		||||
      $tstart = new DateTime();
 | 
			
		||||
      $duration = Delay::with($this->ppDuration, $tstart);
 | 
			
		||||
      fwrite($outf, serialize([$tstart, $duration])."\n");
 | 
			
		||||
      fwrite($outf, $contents);
 | 
			
		||||
    } finally {
 | 
			
		||||
@ -150,19 +149,25 @@ abstract class FileCachedValue extends Parametrable implements ArrayAccess, Coun
 | 
			
		||||
 | 
			
		||||
  protected function loadInfos(): array {
 | 
			
		||||
    [$tstart, $duration] = unserialize(fgets($this->fp));
 | 
			
		||||
    if ($this->ppOverrideDuration) $duration = $this->ppDuration;
 | 
			
		||||
    if (is_int($tstart)) {
 | 
			
		||||
      $tstart = new DateTime($tstart);
 | 
			
		||||
      $duration = new Delay($duration, $tstart);
 | 
			
		||||
    }
 | 
			
		||||
    if ($this->ppOverrideDuration) {
 | 
			
		||||
      $duration = Delay::with($this->ppDuration, $tstart);
 | 
			
		||||
    }
 | 
			
		||||
    return [$tstart, $duration];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected function shouldUpdate(bool $noCache=false) {
 | 
			
		||||
    /** @var Delay $duration */
 | 
			
		||||
    $this->_open();
 | 
			
		||||
    $cleanup = true;
 | 
			
		||||
    try {
 | 
			
		||||
      $this->_lock(LOCK_SH);
 | 
			
		||||
      if ($this->isValidFile()) {
 | 
			
		||||
        $now = time();
 | 
			
		||||
        [$tstart, $duration] = $this->loadInfos();
 | 
			
		||||
        $expired = $now - $tstart > $duration;
 | 
			
		||||
        $expired = $duration->isElapsed();
 | 
			
		||||
      } else {
 | 
			
		||||
        $expired = false;
 | 
			
		||||
        $noCache = true;
 | 
			
		||||
@ -234,16 +239,18 @@ abstract class FileCachedValue extends Parametrable implements ArrayAccess, Coun
 | 
			
		||||
      $this->_lock(LOCK_SH);
 | 
			
		||||
      if (!$this->isValidFile()) return ["valid" => false];
 | 
			
		||||
      $size = filesize($this->ppFile);
 | 
			
		||||
      /**
 | 
			
		||||
       * @var DateTime $tstart
 | 
			
		||||
       * @var Delay $duration
 | 
			
		||||
       */
 | 
			
		||||
      [$tstart, $duration] = $this->loadInfos();
 | 
			
		||||
      $dateStart = new Datetime($tstart);
 | 
			
		||||
      $dateEnd = new Datetime($tstart + $duration);
 | 
			
		||||
      return [
 | 
			
		||||
        "valid" => true,
 | 
			
		||||
        "size" => $size,
 | 
			
		||||
        "tstart" => $tstart,
 | 
			
		||||
        "duration" => $duration,
 | 
			
		||||
        "date_start" => $dateStart->format(),
 | 
			
		||||
        "date_end" => $dateEnd->format(),
 | 
			
		||||
        "duration" => strval($duration),
 | 
			
		||||
        "date_start" => $tstart->format(),
 | 
			
		||||
        "date_end" => $duration->getDest()->format(),
 | 
			
		||||
      ];
 | 
			
		||||
    } finally {
 | 
			
		||||
      $this->cleanup();
 | 
			
		||||
@ -253,17 +260,21 @@ abstract class FileCachedValue extends Parametrable implements ArrayAccess, Coun
 | 
			
		||||
  const UPDATE_SUB = -1, UPDATE_SET = 0, UPDATE_ADD = 1;
 | 
			
		||||
 | 
			
		||||
  /** mettre à jour la durée de validité du fichier */
 | 
			
		||||
  function updateDuration(int $duration, int $action=1): void {
 | 
			
		||||
  function updateDuration($nduration, int $action=1): void {
 | 
			
		||||
    $this->_open();
 | 
			
		||||
    try {
 | 
			
		||||
      $this->_lock(LOCK_SH);
 | 
			
		||||
      if (!$this->isValidFile()) return;
 | 
			
		||||
      $this->_lock(LOCK_EX);
 | 
			
		||||
      $fp = $this->fp;
 | 
			
		||||
      [$tstart, $oduration] = $this->loadInfos();
 | 
			
		||||
      /**
 | 
			
		||||
       * @var DateTime $tstart
 | 
			
		||||
       * @var Delay $duration
 | 
			
		||||
       */
 | 
			
		||||
      [$tstart, $duration] = $this->loadInfos();
 | 
			
		||||
      $contents = stream_get_contents($fp);
 | 
			
		||||
      if ($action < 0) $duration = $oduration - $duration;
 | 
			
		||||
      elseif ($action > 0) $duration = $oduration + $duration;
 | 
			
		||||
      if ($action < 0) $duration->subDuration($nduration);
 | 
			
		||||
      elseif ($action > 0) $duration->addDuration($nduration);
 | 
			
		||||
      fseek($fp, 0);
 | 
			
		||||
      ftruncate($fp, 0);
 | 
			
		||||
      fwrite($fp, serialize([$tstart, $duration])."\n");
 | 
			
		||||
 | 
			
		||||
@ -4,6 +4,11 @@ namespace nur\sery\php\time;
 | 
			
		||||
use InvalidArgumentException;
 | 
			
		||||
 | 
			
		||||
class DateInterval extends \DateInterval {
 | 
			
		||||
  static function with($interval): self {
 | 
			
		||||
    if ($interval instanceof static) return $interval;
 | 
			
		||||
    else return new static($interval);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected static function to_string(DateInterval $interval) {
 | 
			
		||||
    $string = "P";
 | 
			
		||||
    $y = $interval->y;
 | 
			
		||||
@ -24,6 +29,7 @@ class DateInterval extends \DateInterval {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function __construct($duration) {
 | 
			
		||||
    if (is_int($duration)) $duration = "PT${duration}S";
 | 
			
		||||
    if ($duration instanceof \DateInterval) {
 | 
			
		||||
      $this->y = $duration->y;
 | 
			
		||||
      $this->m = $duration->m;
 | 
			
		||||
 | 
			
		||||
@ -24,6 +24,11 @@ use InvalidArgumentException;
 | 
			
		||||
 * @property-read string $YmdHMSZ
 | 
			
		||||
 */
 | 
			
		||||
class DateTime extends \DateTime {
 | 
			
		||||
  static function with($datetime): self {
 | 
			
		||||
    if ($datetime instanceof static) return $datetime;
 | 
			
		||||
    else return new static($datetime);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const DMY_PATTERN = '/^(\d+)\/(\d+)(?:\/(\d+))?$/';
 | 
			
		||||
  const YMD_PATTERN = '/^((?:\d{2})?\d{2})(\d{2})(\d{2})$/';
 | 
			
		||||
  const DMYHIS_PATTERN = '/^(\d+)\/(\d+)(?:\/(\d+))? +(\d+)[h:.](\d+)(?:[:.](\d+))?$/';
 | 
			
		||||
 | 
			
		||||
@ -13,6 +13,7 @@ use InvalidArgumentException;
 | 
			
		||||
 * - une chaine de la forme "x[WDHMS]y" où x et y sont des nombres et la lettre
 | 
			
		||||
 * est l'unité de temps: W représente une semaine, D une journée, H une heure,
 | 
			
		||||
 * M une minute et S une seconde.
 | 
			
		||||
 * - la chaine "INF" qui représente une durée infinie
 | 
			
		||||
 *
 | 
			
		||||
 * Dans cette dernière forme, le timestamp destination est calculé en ajoutant x
 | 
			
		||||
 * unités. puis l'unité inférieure est ramenée à (0 + y)
 | 
			
		||||
@ -24,6 +25,11 @@ use InvalidArgumentException;
 | 
			
		||||
 * NB: la valeur y pour l'unité S est ignorée
 | 
			
		||||
 */
 | 
			
		||||
class Delay {
 | 
			
		||||
  static function with($delay, ?DateTimeInterface $from=null): self {
 | 
			
		||||
    if ($delay instanceof static) return $delay;
 | 
			
		||||
    else return new static($delay, $from);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** valeurs par défaut de x et y pour les unités supportées */
 | 
			
		||||
  const DEFAULTS = [
 | 
			
		||||
    "w" => [0, 5],
 | 
			
		||||
@ -35,6 +41,7 @@ class Delay {
 | 
			
		||||
 | 
			
		||||
  static function compute_dest(int $x, string $u, ?int $y, DateTime $from): array {
 | 
			
		||||
    $dest = DateTime::clone($from);
 | 
			
		||||
    $yu = null;
 | 
			
		||||
    switch ($u) {
 | 
			
		||||
    case "w":
 | 
			
		||||
      if ($x > 0) {
 | 
			
		||||
@ -43,29 +50,28 @@ class Delay {
 | 
			
		||||
      }
 | 
			
		||||
      $w = 7 - intval($dest->format("w"));
 | 
			
		||||
      $dest->add(new \DateInterval("P${w}D"));
 | 
			
		||||
      $u = "h";
 | 
			
		||||
      $yu = "h";
 | 
			
		||||
      break;
 | 
			
		||||
    case "d":
 | 
			
		||||
      $dest->add(new \DateInterval("P${x}D"));
 | 
			
		||||
      $u = "h";
 | 
			
		||||
      $yu = "h";
 | 
			
		||||
      break;
 | 
			
		||||
    case "h":
 | 
			
		||||
      $dest->add(new \DateInterval("PT${x}H"));
 | 
			
		||||
      $u = "m";
 | 
			
		||||
      $yu = "m";
 | 
			
		||||
      break;
 | 
			
		||||
    case "m":
 | 
			
		||||
      $dest->add(new \DateInterval("PT${x}M"));
 | 
			
		||||
      $u = "s";
 | 
			
		||||
      $yu = "s";
 | 
			
		||||
      break;
 | 
			
		||||
    case "s":
 | 
			
		||||
      $dest->add(new \DateInterval("PT${x}S"));
 | 
			
		||||
      $u = null;
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    if ($y !== null && $u !== null) {
 | 
			
		||||
    if ($y !== null && $yu !== null) {
 | 
			
		||||
      $h = intval($dest->format("H"));
 | 
			
		||||
      $m = intval($dest->format("i"));
 | 
			
		||||
      switch ($u) {
 | 
			
		||||
      switch ($yu) {
 | 
			
		||||
      case "h":
 | 
			
		||||
        $dest->setTime($y, 0, 0, 0);
 | 
			
		||||
        break;
 | 
			
		||||
@ -77,13 +83,18 @@ class Delay {
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    $repr = $y !== null? "$x$y$y": "$x";
 | 
			
		||||
    $u = strtoupper($u);
 | 
			
		||||
    $repr = $y !== null? "$x$u$y": "$x";
 | 
			
		||||
    return [$dest, $repr];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function __construct($delay, ?DateTimeInterface $from=null) {
 | 
			
		||||
    if ($from === null) $from = new DateTime();
 | 
			
		||||
    if (is_int($delay)) {
 | 
			
		||||
    if ($delay === "INF") {
 | 
			
		||||
      $dest = DateTime::clone($from);
 | 
			
		||||
      $dest->add(new DateInterval("P9999Y"));
 | 
			
		||||
      $repr = "INF";
 | 
			
		||||
    } elseif (is_int($delay)) {
 | 
			
		||||
      [$dest, $repr] = self::compute_dest($delay, "s", null, $from);
 | 
			
		||||
    } elseif (is_string($delay) && preg_match('/^\d+$/', $delay)) {
 | 
			
		||||
      $x = intval($delay);
 | 
			
		||||
@ -111,6 +122,22 @@ class Delay {
 | 
			
		||||
    return $this->dest;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function addDuration($duration) {
 | 
			
		||||
    if (is_int($duration) && $duration < 0) {
 | 
			
		||||
      $this->dest->sub(DateInterval::with(-$duration));
 | 
			
		||||
    } else {
 | 
			
		||||
      $this->dest->add(DateInterval::with($duration));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function subDuration($duration) {
 | 
			
		||||
    if (is_int($duration) && $duration < 0) {
 | 
			
		||||
      $this->dest->add(DateInterval::with(-$duration));
 | 
			
		||||
    } else {
 | 
			
		||||
      $this->dest->sub(DateInterval::with($duration));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** @var string */
 | 
			
		||||
  protected $repr;
 | 
			
		||||
 | 
			
		||||
@ -125,7 +152,8 @@ class Delay {
 | 
			
		||||
 | 
			
		||||
  /** retourner true si le délai imparti est écoulé */
 | 
			
		||||
  function isElapsed(?DateTimeInterface $now=null): bool {
 | 
			
		||||
    return $this->_getDiff($now)->invert == 0;
 | 
			
		||||
    if ($this->repr === "INF") return false;
 | 
			
		||||
    else return $this->_getDiff($now)->invert == 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user