Improve reblog api performance

This commit is contained in:
Daniel Supernault 2022-03-10 23:34:34 -07:00
parent 36325af076
commit 3ef6c9fe81
No known key found for this signature in database
GPG key ID: 0DEF1C662C9033F7
4 changed files with 57 additions and 20 deletions

View file

@ -1879,7 +1879,7 @@ class ApiV1Controller extends Controller
if($status->profile_id !== $user->profile_id) {
if($status->scope == 'private') {
abort_if(!$status->profile->followedBy($user->profile), 403);
abort_if(!FollowerService::follows($user->profile_id, $status->profile_id), 403);
} else {
abort_if(!in_array($status->scope, ['public','unlisted']), 403);
}
@ -1922,22 +1922,7 @@ class ApiV1Controller extends Controller
public function statusCard(Request $request, $id)
{
abort_if(!$request->user(), 403);
$user = $request->user();
$status = Status::findOrFail($id);
if($status->profile_id !== $user->profile_id) {
if($status->scope == 'private') {
abort_if(!$status->profile->followedBy($user->profile), 403);
} else {
abort_if(!in_array($status->scope, ['public','unlisted']), 403);
}
}
// Return empty response since we don't handle support cards
$res = [];
return response()->json($res);
}
@ -1963,15 +1948,30 @@ class ApiV1Controller extends Controller
if($status->profile_id !== $user->profile_id) {
if($status->scope == 'private') {
abort_if(!$status->profile->followedBy($user->profile), 403);
abort_if(!FollowerService::follows($user->profile_id, $status->profile_id), 403);
} else {
abort_if(!in_array($status->scope, ['public','unlisted']), 403);
}
}
$shared = $status->sharedBy()->latest()->simplePaginate($limit);
$resource = new Fractal\Resource\Collection($shared, new AccountTransformer());
$res = $this->fractal->createData($resource)->toArray();
$page = $request->input('page', 1);
$start = $page == 1 ? 0 : (($page * $limit) - $limit);
$end = $start + $limit - 1;
$ids = ReblogService::getPostReblogs($id, $start, $end);
if(empty($ids)) {
return [];
}
$res = collect($ids)
->map(function($id) {
$status = StatusService::get($id);
return AccountService::get($status['account']['id']);
})
->filter(function($account) {
return $account && isset($account['id']);
})
->values();
$url = $request->url();
$page = $request->input('page', 1);

View file

@ -15,6 +15,7 @@ use League\Fractal\Serializer\ArraySerializer;
use App\Transformer\ActivityPub\Verb\Announce;
use GuzzleHttp\{Pool, Client, Promise};
use App\Util\ActivityPub\HttpSignature;
use App\Services\ReblogService;
use App\Services\StatusService;
class SharePipeline implements ShouldQueue
@ -75,6 +76,8 @@ class SharePipeline implements ShouldQueue
$this->remoteAnnounceDeliver();
ReblogService::addPostReblog($parent->id, $status->id);
$parent->reblogs_count = $parent->shares()->count();
$parent->save();
StatusService::del($parent->id);

View file

@ -15,6 +15,7 @@ use League\Fractal\Serializer\ArraySerializer;
use App\Transformer\ActivityPub\Verb\UndoAnnounce;
use GuzzleHttp\{Pool, Client, Promise};
use App\Util\ActivityPub\HttpSignature;
use App\Services\ReblogService;
use App\Services\StatusService;
class UndoSharePipeline implements ShouldQueue
@ -35,6 +36,8 @@ class UndoSharePipeline implements ShouldQueue
$parent = $status->parent();
$target = $status->parent()->profile;
ReblogService::removePostReblog($parent->id, $status->id);
if ($status->uri !== null) {
return;
}

View file

@ -2,11 +2,15 @@
namespace App\Services;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Redis;
use App\Status;
class ReblogService
{
const CACHE_KEY = 'pf:services:reblogs:';
const REBLOGS_KEY = 'pf:services:reblogs:post:';
const COLDBOOT_KEY = 'pf:services:reblogs:post_:';
public static function get($profileId, $statusId)
{
@ -26,4 +30,31 @@ class ReblogService
{
return Redis::zrem(self::CACHE_KEY . $profileId, $statusId);
}
public static function getPostReblogs($id, $start = 0, $stop = 10)
{
if(!Redis::zcard(self::REBLOGS_KEY . $id)) {
return Cache::remember(self::COLDBOOT_KEY . $id, 86400, function() use($id) {
return Status::whereReblogOfId($id)
->pluck('id')
->each(function($reblog) use($id) {
self::addPostReblog($id, $reblog);
})
->map(function($reblog) {
return (string) $reblog;
});
});
}
return Redis::zrange(self::REBLOGS_KEY . $id, $start, $stop);
}
public static function addPostReblog($parentId, $reblogId)
{
return Redis::zadd(self::REBLOGS_KEY . $parentId, $reblogId);
}
public static function removePostReblog($parentId, $reblogId)
{
return Redis::zrem(self::REBLOGS_KEY . $parentId, $reblogId);
}
}