2016-05-08 15:37:49 +02:00
|
|
|
<?php
|
|
|
|
|
2024-02-16 15:18:17 +01:00
|
|
|
class Queues {
|
|
|
|
private static $queues = array();
|
2016-05-08 15:37:49 +02:00
|
|
|
|
2024-02-16 15:18:17 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* This queue implementation isn't actually ordered, so it works more as a "bag".
|
|
|
|
*/
|
|
|
|
private static function filesystem(string $key, Lock $lock): Queue {
|
|
|
|
$key = str_replace('/', '::', $key);
|
|
|
|
$key = str_replace("\0", '', $key);
|
|
|
|
$key = "tmp/queue/$key/";
|
|
|
|
|
|
|
|
return new class($key, $lock) implements Queue {
|
|
|
|
private Lock $lock;
|
|
|
|
private string $key;
|
|
|
|
|
|
|
|
|
|
|
|
function __construct(string $key, Lock $lock) {
|
|
|
|
$this->lock = $lock;
|
|
|
|
$this->key = $key;
|
|
|
|
}
|
|
|
|
|
2024-02-16 15:48:18 +01:00
|
|
|
public function push(string $str): bool {
|
2024-02-16 15:18:17 +01:00
|
|
|
$this->lock->get_ex();
|
2024-02-16 15:48:18 +01:00
|
|
|
$ret = file_put_contents($this->key . microtime(true), $str);
|
2024-02-16 15:18:17 +01:00
|
|
|
$this->lock->free();
|
2024-02-16 15:48:18 +01:00
|
|
|
return $ret !== false;
|
2024-02-16 15:18:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function pop(int $n = 1): array {
|
|
|
|
$this->lock->get_ex();
|
|
|
|
$dir = opendir($this->key);
|
|
|
|
$paths = array();
|
|
|
|
|
|
|
|
while ($n > 0) {
|
|
|
|
$path = readdir($dir);
|
|
|
|
if ($path === false) {
|
|
|
|
break;
|
|
|
|
} elseif ($path == '.' || $path == '..') {
|
|
|
|
continue;
|
|
|
|
} else {
|
|
|
|
$paths[] = $path;
|
|
|
|
$n--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$out = array();
|
|
|
|
foreach ($paths as $v) {
|
|
|
|
$out[] = file_get_contents($this->key . $v);
|
|
|
|
unlink($this->key . $v);
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->lock->free();
|
|
|
|
return $out;
|
|
|
|
}
|
|
|
|
};
|
2024-02-16 14:48:42 +01:00
|
|
|
}
|
2016-05-08 15:37:49 +02:00
|
|
|
|
2024-02-16 15:18:17 +01:00
|
|
|
/**
|
|
|
|
* No-op. Can be used for mocking.
|
|
|
|
*/
|
|
|
|
public static function none(): Queue {
|
|
|
|
return new class() implements Queue {
|
2024-02-16 15:48:18 +01:00
|
|
|
public function push(string $str): bool {
|
|
|
|
return true;
|
2024-02-16 14:48:42 +01:00
|
|
|
}
|
2024-02-16 15:18:17 +01:00
|
|
|
|
|
|
|
public function pop(int $n = 1): array {
|
|
|
|
return array();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function get_queue(array $config, string $name): Queue|false {
|
|
|
|
if (!isset(self::$queues[$name])) {
|
|
|
|
if ($config['queue']['enabled'] == 'fs') {
|
|
|
|
$lock = Locks::get_lock($config, $name);
|
|
|
|
if ($lock === false) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
self::$queues[$name] = self::filesystem($name, $lock);
|
|
|
|
} else {
|
|
|
|
self::$queues[$name] = self::none();
|
2024-02-16 14:48:42 +01:00
|
|
|
}
|
|
|
|
}
|
2024-02-16 15:18:17 +01:00
|
|
|
return self::$queues[$name];
|
2024-02-16 14:48:42 +01:00
|
|
|
}
|
2016-05-08 15:37:49 +02:00
|
|
|
}
|
|
|
|
|
2024-02-16 15:18:17 +01:00
|
|
|
interface Queue {
|
|
|
|
// Push a string in the queue.
|
2024-02-16 15:48:18 +01:00
|
|
|
public function push(string $str): bool;
|
2016-05-08 15:37:49 +02:00
|
|
|
|
2024-02-16 15:18:17 +01:00
|
|
|
// Get a string from the queue.
|
|
|
|
public function pop(int $n = 1): array;
|
2016-05-08 15:37:49 +02:00
|
|
|
}
|