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/array.php';
|
||||||
require_once 'src/audit_log.php';
|
require_once 'src/audit_log.php';
|
||||||
|
require_once 'src/cache.php';
|
||||||
require_once 'src/changelog.php';
|
require_once 'src/changelog.php';
|
||||||
require_once 'src/colour.php';
|
require_once 'src/colour.php';
|
||||||
require_once 'src/comments.php';
|
require_once 'src/comments.php';
|
||||||
|
@ -244,14 +245,7 @@ MIG;
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
new Cache(
|
cache_init(config_get_default([], 'Cache'));
|
||||||
config_get('Cache', 'host'),
|
|
||||||
config_get('Cache', 'port'),
|
|
||||||
config_get('Cache', 'database'),
|
|
||||||
config_get('Cache', 'password'),
|
|
||||||
config_get_default('', 'Cache', 'prefix')
|
|
||||||
);
|
|
||||||
|
|
||||||
geoip_init(config_get_default('', 'GeoIP', 'database_path'));
|
geoip_init(config_get_default('', 'GeoIP', 'database_path'));
|
||||||
|
|
||||||
tpl_init([
|
tpl_init([
|
||||||
|
|
|
@ -33,7 +33,7 @@ $news = Database::query('
|
||||||
LIMIT 5
|
LIMIT 5
|
||||||
')->fetchAll(PDO::FETCH_ASSOC);
|
')->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
$statistics = Cache::instance()->get('index:stats:v1', function () {
|
$statistics = cache_get('index:stats:v1', function () {
|
||||||
return [
|
return [
|
||||||
'users' => (int)Database::query('
|
'users' => (int)Database::query('
|
||||||
SELECT COUNT(`user_id`)
|
SELECT COUNT(`user_id`)
|
||||||
|
@ -52,7 +52,7 @@ $statistics = Cache::instance()->get('index:stats:v1', function () {
|
||||||
];
|
];
|
||||||
}, 10800);
|
}, 10800);
|
||||||
|
|
||||||
$changelog = Cache::instance()->get('index:changelog:v1', function () {
|
$changelog = cache_get('index:changelog:v1', function () {
|
||||||
return Database::query('
|
return Database::query('
|
||||||
SELECT
|
SELECT
|
||||||
c.`change_id`, c.`change_log`,
|
c.`change_id`, c.`change_log`,
|
||||||
|
@ -67,7 +67,7 @@ $changelog = Cache::instance()->get('index:changelog:v1', function () {
|
||||||
')->fetchAll(PDO::FETCH_ASSOC);
|
')->fetchAll(PDO::FETCH_ASSOC);
|
||||||
}, 1800);
|
}, 1800);
|
||||||
|
|
||||||
$onlineUsers = Cache::instance()->get('index:online:v1', function () {
|
$onlineUsers = cache_get('index:online:v1', function () {
|
||||||
return Database::query('
|
return Database::query('
|
||||||
SELECT
|
SELECT
|
||||||
u.`user_id`, u.`username`,
|
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