[CACHE] Fix bug in list caching
This commit is contained in:
parent
496dec4254
commit
459f0bf41f
@ -34,45 +34,23 @@ use App\Core\Controller;
|
|||||||
use App\Core\DB\DB;
|
use App\Core\DB\DB;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
|
||||||
class NetworkPublic extends Controller
|
class Network extends Controller
|
||||||
{
|
{
|
||||||
public function public(Request $request)
|
public function public(Request $request)
|
||||||
{
|
{
|
||||||
$notes = DB::findBy('note', [], ['created' => 'DESC']);
|
|
||||||
$attachments = [];
|
|
||||||
foreach ($notes as $n) {
|
|
||||||
$a = DB::dql(
|
|
||||||
'select f from App\Entity\File f ' .
|
|
||||||
'join App\Entity\FileToNote ftn with ftn.file_id = f.id ' .
|
|
||||||
'where ftn.note_id = :note_id',
|
|
||||||
['note_id' => $n->getId()]
|
|
||||||
);
|
|
||||||
$attachments[] = $a;
|
|
||||||
}
|
|
||||||
return [
|
return [
|
||||||
'_template' => 'network/public.html.twig',
|
'_template' => 'network/public.html.twig',
|
||||||
'notes' => $notes,
|
'notes' => DB::dql('select n from App\Entity\Note n ' .
|
||||||
'attachments' => array_reverse($attachments),
|
'where n.reply_to is null order by n.created DESC'),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function home(Request $request)
|
public function home(Request $request)
|
||||||
{
|
{
|
||||||
$notes = DB::findBy('note', [], ['created' => 'DESC']);
|
$notes = DB::findBy('note', [], ['created' => 'DESC']);
|
||||||
$attachments = [];
|
|
||||||
foreach ($notes as $n) {
|
|
||||||
$a = DB::dql(
|
|
||||||
'select f from App\Entity\File f ' .
|
|
||||||
'join App\Entity\FileToNote ftn with ftn.file_id = f.id ' .
|
|
||||||
'where ftn.note_id = :note_id',
|
|
||||||
['note_id' => $n->getId()]
|
|
||||||
);
|
|
||||||
$attachments[] = $a;
|
|
||||||
}
|
|
||||||
return [
|
return [
|
||||||
'_template' => 'network/public.html.twig',
|
'_template' => 'network/public.html.twig',
|
||||||
'notes' => $notes,
|
'notes' => $notes,
|
||||||
'attachments' => array_reverse($attachments),
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,7 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// {{{ License
|
// {{{ License
|
||||||
|
|
||||||
// This file is part of GNU social - https://www.gnu.org/software/social
|
// This file is part of GNU social - https://www.gnu.org/software/social
|
||||||
//
|
//
|
||||||
// GNU social is free software: you can redistribute it and/or modify
|
// GNU social is free software: you can redistribute it and/or modify
|
||||||
@ -16,7 +15,6 @@
|
|||||||
//
|
//
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
|
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
namespace App\Core;
|
namespace App\Core;
|
||||||
@ -24,6 +22,7 @@ namespace App\Core;
|
|||||||
use Functional as F;
|
use Functional as F;
|
||||||
use Redis;
|
use Redis;
|
||||||
use RedisCluster;
|
use RedisCluster;
|
||||||
|
use SplFixedArray;
|
||||||
use Symfony\Component\Cache\Adapter;
|
use Symfony\Component\Cache\Adapter;
|
||||||
use Symfony\Component\Cache\Adapter\ChainAdapter;
|
use Symfony\Component\Cache\Adapter\ChainAdapter;
|
||||||
|
|
||||||
@ -81,8 +80,8 @@ abstract class Cache
|
|||||||
$r->setOption($class::OPT_TCP_KEEPALIVE, true);
|
$r->setOption($class::OPT_TCP_KEEPALIVE, true);
|
||||||
// Use LZ4 for the improved decompression speed (while keeping an okay compression ratio)
|
// Use LZ4 for the improved decompression speed (while keeping an okay compression ratio)
|
||||||
$r->setOption($class::OPT_COMPRESSION, $class::COMPRESSION_LZ4);
|
$r->setOption($class::OPT_COMPRESSION, $class::COMPRESSION_LZ4);
|
||||||
self::$redis[$pool][] = $r;
|
self::$redis[$pool] = $r;
|
||||||
$adapters[$pool][] = new Adapter\RedisAdapter($r);
|
$adapters[$pool][] = new Adapter\RedisAdapter($r);
|
||||||
break;
|
break;
|
||||||
case 'memcached':
|
case 'memcached':
|
||||||
// memcached can also have multiple servers
|
// memcached can also have multiple servers
|
||||||
@ -131,17 +130,38 @@ abstract class Cache
|
|||||||
return self::$pools[$pool]->delete($key);
|
return self::$pools[$pool]->delete($key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getList(string $key, callable $calculate, string $pool = 'default', int $max_count = 64, float $beta = 1.0): SplFixedArray
|
public static function getList(string $key, callable $calculate, string $pool = 'default', int $max_count = -1, float $beta = 1.0): array
|
||||||
{
|
{
|
||||||
if (isset(self::$redis[$pool])) {
|
if (isset(self::$redis[$pool])) {
|
||||||
return SplFixedArray::fromArray(self::$redis[$pool]->lRange($key, 0, -1));
|
if (!($recompute = $beta === INF || !(self::$redis[$pool]->exists($key)))) {
|
||||||
|
if (!($_ENV['REDIS_CACHE_USE_EXPONENTIAL_UPDATE'] ?? false)) {
|
||||||
|
$recompute = (mt_rand() / mt_getrandmax() > ((float) ($_ENV['REDIS_CACHE_RANDOM_UPDATE'] ?? 0.95)));
|
||||||
|
Log::info('Item "{key}" elected for early recomputation', ['key' => $key]);
|
||||||
|
} else {
|
||||||
|
if ($recompute = ($idletime = self::$redis[$pool]->object('idletime', $key) ?? false) && ($expiry = self::$redis[$pool]->ttl($key) ?? false) && $expiry <= $idletime / 1000 * $beta * log(random_int(1, PHP_INT_MAX) / PHP_INT_MAX)) {
|
||||||
|
Log::info('Item "{key}" elected for early recomputation {delta}s before its expiration', [
|
||||||
|
'key' => $key,
|
||||||
|
'delta' => sprintf('%.1f', $expiry - microtime(true)),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($recompute) {
|
||||||
|
$save = true;
|
||||||
|
$res = $calculate(null, $save);
|
||||||
|
if ($save) {
|
||||||
|
self::$redis[$pool]->del($key);
|
||||||
|
self::$redis[$pool]->lPush($key, ...$res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return self::$redis[$pool]->lRange($key, 0, $max_count);
|
||||||
} else {
|
} else {
|
||||||
$keys = self::getKeyList($key, $max_count, $beta);
|
$keys = self::getKeyList($key, $max_count, $beta);
|
||||||
$list = new SplFixedArray($keys->count());
|
$list = new SplFixedArray($keys->count());
|
||||||
foreach ($keys as $k) {
|
foreach ($keys as $k) {
|
||||||
$list[] = self::get($k, $calculate, $pool, $beta);
|
$list[] = self::get($k, $calculate, $pool, $beta);
|
||||||
}
|
}
|
||||||
return $list;
|
return $list->toArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user