2016-12-30 03:59:59 +01:00
|
|
|
<?php
|
2015-08-08 16:09:07 +02:00
|
|
|
|
|
|
|
namespace Amp\File;
|
|
|
|
|
2017-03-17 04:39:49 +01:00
|
|
|
use Amp\Loop;
|
2016-07-21 01:33:03 +02:00
|
|
|
|
2018-10-27 17:57:31 +02:00
|
|
|
class StatCache
|
|
|
|
{
|
2015-08-08 16:09:07 +02:00
|
|
|
private static $cache = [];
|
|
|
|
private static $timeouts = [];
|
|
|
|
private static $ttl = 3;
|
|
|
|
private static $now = null;
|
|
|
|
|
2018-10-27 17:57:31 +02:00
|
|
|
private static function init()
|
|
|
|
{
|
2015-08-08 16:09:07 +02:00
|
|
|
self::$now = \time();
|
2017-06-20 17:40:47 +02:00
|
|
|
|
2016-07-21 01:33:03 +02:00
|
|
|
$watcher = Loop::repeat(1000, function () {
|
2015-08-08 16:09:07 +02:00
|
|
|
self::$now = $now = \time();
|
|
|
|
foreach (self::$cache as $path => $expiry) {
|
|
|
|
if ($now > $expiry) {
|
|
|
|
unset(
|
|
|
|
self::$cache[$path],
|
|
|
|
self::$timeouts[$path]
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2016-07-21 01:33:03 +02:00
|
|
|
});
|
2017-06-20 17:40:47 +02:00
|
|
|
|
2016-07-21 01:33:03 +02:00
|
|
|
Loop::unreference($watcher);
|
2017-06-20 22:59:23 +02:00
|
|
|
|
2017-06-21 10:18:14 +02:00
|
|
|
Loop::setState(self::class, new class($watcher) {
|
2017-06-20 22:59:23 +02:00
|
|
|
private $watcher;
|
|
|
|
private $driver;
|
|
|
|
|
2018-10-27 17:57:31 +02:00
|
|
|
public function __construct(string $watcher)
|
|
|
|
{
|
2017-06-20 22:59:23 +02:00
|
|
|
$this->watcher = $watcher;
|
|
|
|
$this->driver = Loop::get();
|
|
|
|
}
|
|
|
|
|
2018-10-27 17:57:31 +02:00
|
|
|
public function __destruct()
|
|
|
|
{
|
2017-06-20 22:59:23 +02:00
|
|
|
$this->driver->cancel($this->watcher);
|
|
|
|
}
|
|
|
|
});
|
2015-08-08 16:09:07 +02:00
|
|
|
}
|
|
|
|
|
2018-10-27 17:57:31 +02:00
|
|
|
public static function get(string $path)
|
|
|
|
{
|
2015-08-08 16:09:07 +02:00
|
|
|
return isset(self::$cache[$path]) ? self::$cache[$path] : null;
|
|
|
|
}
|
|
|
|
|
2018-10-27 17:57:31 +02:00
|
|
|
public static function set(string $path, array $stat)
|
|
|
|
{
|
2015-08-08 16:09:07 +02:00
|
|
|
if (self::$ttl <= 0) {
|
|
|
|
return;
|
|
|
|
}
|
2017-06-20 17:40:47 +02:00
|
|
|
|
|
|
|
if (Loop::getState(self::class) === null) {
|
2015-08-08 16:09:07 +02:00
|
|
|
self::init();
|
|
|
|
}
|
2017-06-20 17:40:47 +02:00
|
|
|
|
2015-08-08 16:09:07 +02:00
|
|
|
self::$cache[$path] = $stat;
|
|
|
|
self::$timeouts[$path] = self::$now + self::$ttl;
|
|
|
|
}
|
|
|
|
|
2018-10-27 17:57:31 +02:00
|
|
|
public static function ttl(int $seconds)
|
|
|
|
{
|
2016-08-24 06:55:06 +02:00
|
|
|
self::$ttl = $seconds;
|
2015-08-08 16:09:07 +02:00
|
|
|
}
|
|
|
|
|
2018-10-27 17:57:31 +02:00
|
|
|
public static function clear(string $path = null)
|
|
|
|
{
|
2015-08-08 16:09:07 +02:00
|
|
|
if (isset($path)) {
|
|
|
|
unset(
|
|
|
|
self::$cache[$path],
|
|
|
|
self::$timeouts[$path]
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
self::$cache = [];
|
|
|
|
self::$timeouts = [];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|