pixelfed/app/Services/ProfileStatusService.php
2022-09-12 21:26:22 -06:00

66 lines
1.8 KiB
PHP

<?php
namespace App\Services;
use DB;
use Illuminate\Support\Facades\Redis;
class ProfileStatusService
{
const CACHE_KEY = 'pf:services:profile-statuses:ids:';
const COLD_CHECK_KEY = 'pf:services:profile-statuses:id-ttl:';
const FALLOFF_LIMIT = 40;
public static function get($id, $start = 0, $stop = 8)
{
$key = self::CACHE_KEY . $id;
if(!Redis::zscore(self::COLD_CHECK_KEY, $id)) {
$res = self::coldFetch($id);
if($res && count($res)) {
return array_slice($res, $start, $stop);
}
}
$ids = Redis::zrevrange($key, $start, $stop - 1);
return $ids;
}
public static function count($id)
{
return Redis::zcount(self::CACHE_KEY . $id, '-inf', '+inf');
}
public static function add($pid, $sid)
{
if(self::count($pid) > self::FALLOFF_LIMIT) {
Redis::zpopmin(self::CACHE_KEY . $pid);
}
return Redis::zadd(self::CACHE_KEY . $pid, $sid, $sid);
}
public static function delete($pid, $sid)
{
return Redis::zrem(self::CACHE_KEY . $pid, $sid);
}
public static function coldFetch($pid)
{
Redis::del(self::CACHE_KEY . $pid);
$ids = DB::table('statuses')
->select('id', 'profile_id', 'type', 'scope')
->whereIn('type', ['photo', 'photo:album', 'video'])
->whereIn('scope', ['public', 'unlisted'])
->whereProfileId($pid)
->orderByDesc('id')
->limit(self::FALLOFF_LIMIT)
->pluck('id')
->toArray();
if($ids && count($ids)) {
foreach($ids as $id) {
self::add($pid, $id);
}
}
Redis::zadd(self::COLD_CHECK_KEY, $pid, $pid);
return $ids;
}
}