Caching but it's procedural now.
This commit is contained in:
parent
a480678b11
commit
fb93b908c9
4 changed files with 139 additions and 137 deletions
10
misuzu.php
10
misuzu.php
|
@ -28,6 +28,7 @@ $errorHandler->register();
|
|||
|
||||
require_once 'src/array.php';
|
||||
require_once 'src/audit_log.php';
|
||||
require_once 'src/cache.php';
|
||||
require_once 'src/changelog.php';
|
||||
require_once 'src/colour.php';
|
||||
require_once 'src/comments.php';
|
||||
|
@ -244,14 +245,7 @@ MIG;
|
|||
exit;
|
||||
}
|
||||
|
||||
new Cache(
|
||||
config_get('Cache', 'host'),
|
||||
config_get('Cache', 'port'),
|
||||
config_get('Cache', 'database'),
|
||||
config_get('Cache', 'password'),
|
||||
config_get_default('', 'Cache', 'prefix')
|
||||
);
|
||||
|
||||
cache_init(config_get_default([], 'Cache'));
|
||||
geoip_init(config_get_default('', 'GeoIP', 'database_path'));
|
||||
|
||||
tpl_init([
|
||||
|
|
|
@ -33,7 +33,7 @@ $news = Database::query('
|
|||
LIMIT 5
|
||||
')->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
$statistics = Cache::instance()->get('index:stats:v1', function () {
|
||||
$statistics = cache_get('index:stats:v1', function () {
|
||||
return [
|
||||
'users' => (int)Database::query('
|
||||
SELECT COUNT(`user_id`)
|
||||
|
@ -52,7 +52,7 @@ $statistics = Cache::instance()->get('index:stats:v1', function () {
|
|||
];
|
||||
}, 10800);
|
||||
|
||||
$changelog = Cache::instance()->get('index:changelog:v1', function () {
|
||||
$changelog = cache_get('index:changelog:v1', function () {
|
||||
return Database::query('
|
||||
SELECT
|
||||
c.`change_id`, c.`change_log`,
|
||||
|
@ -67,7 +67,7 @@ $changelog = Cache::instance()->get('index:changelog:v1', function () {
|
|||
')->fetchAll(PDO::FETCH_ASSOC);
|
||||
}, 1800);
|
||||
|
||||
$onlineUsers = Cache::instance()->get('index:online:v1', function () {
|
||||
$onlineUsers = cache_get('index:online:v1', function () {
|
||||
return Database::query('
|
||||
SELECT
|
||||
u.`user_id`, u.`username`,
|
||||
|
|
126
src/Cache.php
126
src/Cache.php
|
@ -1,126 +0,0 @@
|
|||
<?php
|
||||
namespace Misuzu;
|
||||
|
||||
use Redis;
|
||||
use InvalidArgumentException;
|
||||
use UnexpectedValueException;
|
||||
|
||||
final class Cache
|
||||
{
|
||||
/**
|
||||
* @var Cache
|
||||
*/
|
||||
private static $instance;
|
||||
|
||||
private $redis;
|
||||
|
||||
public static function instance(): Cache
|
||||
{
|
||||
if (!self::hasInstance()) {
|
||||
throw new UnexpectedValueException('No instance of Cache exists yet.');
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
public function getRedis(): Redis
|
||||
{
|
||||
return $this->redis;
|
||||
}
|
||||
|
||||
public static function hasInstance(): bool
|
||||
{
|
||||
return self::$instance instanceof static;
|
||||
}
|
||||
|
||||
public function __construct(
|
||||
string $host,
|
||||
?int $port = null,
|
||||
?int $database = null,
|
||||
?string $password = null,
|
||||
string $prefix = ''
|
||||
) {
|
||||
if (self::hasInstance()) {
|
||||
throw new UnexpectedValueException('Only one instance of Cache may exist.');
|
||||
}
|
||||
|
||||
self::$instance = $this;
|
||||
$this->redis = new Redis;
|
||||
$this->redis->connect($host, $port);
|
||||
|
||||
if ($password !== null && !$this->redis->auth($password)) {
|
||||
throw new InvalidArgumentException('Redis auth failed.');
|
||||
}
|
||||
|
||||
if ($database !== null && !$this->redis->select($database)) {
|
||||
throw new UnexpectedValueException('Redis select failed.');
|
||||
}
|
||||
|
||||
$this->redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_PHP);
|
||||
$this->redis->setOption(Redis::OPT_PREFIX, $prefix);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->redis->close();
|
||||
self::$instance = null;
|
||||
}
|
||||
|
||||
public function set(string $key, $value, int $ttl = 0)
|
||||
{
|
||||
if (is_callable($value)) {
|
||||
$value = $value();
|
||||
}
|
||||
|
||||
if ($ttl < 0) {
|
||||
return $value;
|
||||
} elseif ($ttl < 1) {
|
||||
$this->redis->set($key, $value);
|
||||
} else {
|
||||
$this->redis->setEx($key, $ttl, $value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function exists(string $key): bool
|
||||
{
|
||||
return $this->redis->exists($key);
|
||||
}
|
||||
|
||||
public function delete($keys): int
|
||||
{
|
||||
return $this->redis->delete($keys);
|
||||
}
|
||||
|
||||
public function increment(string $key, int $amount = 1): int
|
||||
{
|
||||
if ($amount <= 1) {
|
||||
return $this->redis->incr($key);
|
||||
}
|
||||
|
||||
return $this->redis->incrBy($key, $amount);
|
||||
}
|
||||
|
||||
public function decrement(string $key, int $amount = 1): int
|
||||
{
|
||||
if ($amount <= 1) {
|
||||
return $this->redis->decr($key);
|
||||
}
|
||||
|
||||
return $this->redis->decrBy($key, $amount);
|
||||
}
|
||||
|
||||
public function get(string $key, $fallback, int $ttl = 0)
|
||||
{
|
||||
if ($ttl < 0) {
|
||||
return is_callable($fallback) ? $fallback() : $fallback;
|
||||
}
|
||||
|
||||
if (!$this->exists($key)) {
|
||||
return $this->set($key, $fallback, $ttl);
|
||||
}
|
||||
|
||||
return $this->redis->get($key);
|
||||
}
|
||||
}
|
134
src/cache.php
Normal file
134
src/cache.php
Normal file
|
@ -0,0 +1,134 @@
|
|||
<?php
|
||||
define('MSZ_CACHE_REDIS_STORE', '_msz_cache_redis');
|
||||
define('MSZ_CACHE_OPTIONS_STORE', '_msz_cache_options');
|
||||
|
||||
define('MSZ_CACHE_INIT_OK', 0);
|
||||
define('MSZ_CACHE_INIT_ACTIVE', 1);
|
||||
define('MSZ_CACHE_INIT_FAIL', 2);
|
||||
define('MSZ_CACHE_INIT_AUTH', 3);
|
||||
define('MSZ_CACHE_INIT_DATABASE', 4);
|
||||
|
||||
function cache_init(array $options, bool $start = false): void
|
||||
{
|
||||
$GLOBALS[MSZ_CACHE_OPTIONS_STORE] = $options;
|
||||
|
||||
if ($start) {
|
||||
cache_start();
|
||||
}
|
||||
}
|
||||
|
||||
function cache_start(?array $options = null): bool
|
||||
{
|
||||
if (!empty($GLOBALS[MSZ_CACHE_REDIS_STORE])) {
|
||||
return MSZ_CACHE_INIT_ACTIVE;
|
||||
}
|
||||
|
||||
if ($options === null) {
|
||||
$options = $GLOBALS[MSZ_CACHE_OPTIONS_STORE] ?? [];
|
||||
}
|
||||
|
||||
if (empty($options['host'])) {
|
||||
// if no host is present we just act as a void
|
||||
return MSZ_CACHE_INIT_OK;
|
||||
}
|
||||
|
||||
$redis = new Redis;
|
||||
|
||||
if (!$redis->connect($options['host'], $options['port'] ?? null)) {
|
||||
return MSZ_CACHE_INIT_FAIL;
|
||||
}
|
||||
|
||||
if (!empty($options['password']) && !$redis->auth($options['password'])) {
|
||||
return MSZ_CACHE_INIT_AUTH;
|
||||
}
|
||||
|
||||
if (!empty($options['database']) && !$redis->select($options['database'])) {
|
||||
return MSZ_CACHE_INIT_DATABASE;
|
||||
}
|
||||
|
||||
$redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_PHP);
|
||||
$redis->setOption(Redis::OPT_PREFIX, $options['prefix'] ?? '');
|
||||
|
||||
$GLOBALS[MSZ_CACHE_REDIS_STORE] = $redis;
|
||||
return MSZ_CACHE_INIT_OK;
|
||||
}
|
||||
|
||||
function cache_available(): bool
|
||||
{
|
||||
if (!empty($GLOBALS[MSZ_CACHE_REDIS_STORE])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$startUp = cache_start();
|
||||
return $startUp === MSZ_CACHE_INIT_OK || $startUp === MSZ_CACHE_INIT_ACTIVE;
|
||||
}
|
||||
|
||||
function cache_exists(string $key): bool
|
||||
{
|
||||
return cache_available() && $GLOBALS[MSZ_CACHE_REDIS_STORE]->exists($key);
|
||||
}
|
||||
|
||||
function cache_remove($keys): int
|
||||
{
|
||||
if (!cache_available()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $GLOBALS[MSZ_CACHE_REDIS_STORE]->delete($keys);
|
||||
}
|
||||
|
||||
function cache_get(string $key, $fallback, int $ttl = 0)
|
||||
{
|
||||
if (!cache_available() || $ttl < 0) {
|
||||
return is_callable($fallback) ? $fallback() : $fallback;
|
||||
}
|
||||
|
||||
if (!cache_exists($key)) {
|
||||
return cache_set($key, $fallback, $ttl);
|
||||
}
|
||||
|
||||
return $GLOBALS[MSZ_CACHE_REDIS_STORE]->get($key);
|
||||
}
|
||||
|
||||
function cache_set(string $key, $value, int $ttl = 0)
|
||||
{
|
||||
if (is_callable($value)) {
|
||||
$value = $value();
|
||||
}
|
||||
|
||||
if (!cache_available() || $ttl < 0) {
|
||||
return $value;
|
||||
} elseif ($ttl < 1) {
|
||||
$GLOBALS[MSZ_CACHE_REDIS_STORE]->set($key, $value);
|
||||
} else {
|
||||
$GLOBALS[MSZ_CACHE_REDIS_STORE]->setEx($key, $ttl, $value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
function cache_increment(string $key, int $amount = 1): int
|
||||
{
|
||||
if (!cache_available()) {
|
||||
return abs($amount);
|
||||
}
|
||||
|
||||
if ($amount <= 1) {
|
||||
return $GLOBALS[MSZ_CACHE_REDIS_STORE]->incr($key);
|
||||
}
|
||||
|
||||
return $GLOBALS[MSZ_CACHE_REDIS_STORE]->incrBy($key, $amount);
|
||||
}
|
||||
|
||||
function cache_decrement(string $key, int $amount = 1): int
|
||||
{
|
||||
if (!cache_available()) {
|
||||
return abs($amount) * -1;
|
||||
}
|
||||
|
||||
if ($amount <= 1) {
|
||||
return $GLOBALS[MSZ_CACHE_REDIS_STORE]->decr($key);
|
||||
}
|
||||
|
||||
return $GLOBALS[MSZ_CACHE_REDIS_STORE]->decrBy($key, $amount);
|
||||
}
|
Loading…
Add table
Reference in a new issue