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…
Reference in New Issue