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