1
0
mirror of https://github.com/vichan-devel/vichan.git synced 2024-11-23 23:20:57 +01:00

cache: implement cache locking for filesystem cache and give it multiprocess support

This commit is contained in:
Zankaria 2024-04-11 19:20:19 +02:00
parent 82ea1815fd
commit b57d9bfbb3

View File

@ -122,7 +122,7 @@ class CacheDrivers {
};
}
public static function filesystem(string $prefix, string $base_path) {
public static function filesystem(string $prefix, string $base_path, string $lock_file) {
if ($base_path[strlen($base_path) - 1] !== '/') {
$base_path = "$base_path/";
}
@ -135,9 +135,17 @@ class CacheDrivers {
throw new RuntimeException("$base_path is not writable!");
}
return new class($prefix, $base_path) implements CacheDriver {
$lock_file = $base_path . $lock_file;
$lock_fd = fopen($lock_file, 'w');
if ($lock_fd === false) {
throw new RuntimeException('Unable to open the lock file!');
}
$ret = new class($prefix, $base_path, $lock_file) implements CacheDriver {
private string $prefix;
private string $base_path;
private mixed $lock_fd;
private function prepareKey(string $key): string {
@ -146,21 +154,38 @@ class CacheDrivers {
return $this->prefix . $key;
}
public function __construct(string $prefix, string $base_path) {
private function sharedLockCache(): void {
flock($this->lock_fd, LOCK_SH);
}
private function exclusiveLockCache(): void {
flock($this->lock_fd, LOCK_EX);
}
private function unlockCache(): void {
flock($this->lock_fd, LOCK_UN);
}
public function __construct(string $prefix, string $base_path, mixed $lock_fd) {
$this->prefix = $prefix;
$this->base_path = $base_path;
$this->lock_fd = $lock_fd;
}
public function get(string $key): mixed {
$key = $this->prepareKey($key);
$fd = fopen("$this->base_path/$key", 'r');
$this->sharedLockCache();
$fd = fopen($this->base_path . $key, 'r');
if ($fd === false) {
$this->unlockCache();
return null;
}
$data = stream_get_contents("$this->base_path/$key");
$data = stream_get_contents($fd);
fclose($fd);
$this->unlockCache();
return json_decode($data, true);
}
@ -168,22 +193,36 @@ class CacheDrivers {
$key = $this->prepareKey($key);
$data = json_encode($value);
file_put_contents("$this->base_path/$key", $data);
$this->exclusiveLockCache();
file_put_contents($this->base_path . $key, $data);
$this->unlockCache();
}
public function delete(string $key): void {
$key = $this->prepareKey($key);
@unlink("$this->base_path/$key");
$this->exclusiveLockCache();
@unlink($this->base_path . $key);
$this->unlockCache();
}
public function flush(): void {
$files = glob("$this->base_path/$this->prefix*");
$this->exclusiveLockCache();
$files = glob($this->base_path . $this->prefix . '*', GLOB_NOSORT);
foreach ($files as $file) {
@unlink($file);
}
$this->unlockCache();
}
public function close() {
fclose($this->lock_fd);
}
};
register_shutdown_function([$ret, 'close']);
return $ret;
}
public static function phpArray() {