From 4d0cb32f79b52c47ff19d4f3b08b67c5edca4201 Mon Sep 17 00:00:00 2001 From: Anil Kulkarni Date: Sun, 12 Jan 2025 11:29:05 -0800 Subject: [PATCH] Fix notifications not being delivered by directly checking the state from the database --- app/Console/Commands/PushGatewayRefresh.php | 2 - .../Controllers/Api/ApiV1Dot1Controller.php | 18 --- app/Services/PushNotificationService.php | 114 +----------------- 3 files changed, 4 insertions(+), 130 deletions(-) diff --git a/app/Console/Commands/PushGatewayRefresh.php b/app/Console/Commands/PushGatewayRefresh.php index 3b839b6af..dc628bf78 100644 --- a/app/Console/Commands/PushGatewayRefresh.php +++ b/app/Console/Commands/PushGatewayRefresh.php @@ -51,8 +51,6 @@ class PushGatewayRefresh extends Command $recheck = NotificationAppGatewayService::forceSupportRecheck(); if ($recheck) { $this->info('Success! Push Notifications are now active!'); - PushNotificationService::warmList('like'); - return; } else { $this->error('Error, please ensure you have a valid API key.'); diff --git a/app/Http/Controllers/Api/ApiV1Dot1Controller.php b/app/Http/Controllers/Api/ApiV1Dot1Controller.php index 456f22da7..5bfbe8ad5 100644 --- a/app/Http/Controllers/Api/ApiV1Dot1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Dot1Controller.php @@ -1058,8 +1058,6 @@ class ApiV1Dot1Controller extends Controller 'notify_comment' => false, ]); - PushNotificationService::removeMemberFromAll($request->user()->profile_id); - $user = $request->user(); return $this->json([ @@ -1145,31 +1143,15 @@ class ApiV1Dot1Controller extends Controller if ($request->filled('notify_like')) { $request->user()->update(['notify_like' => (bool) $request->boolean('notify_like')]); - $request->boolean('notify_like') == true ? - PushNotificationService::set('like', $pid) : - PushNotificationService::removeMember('like', $pid); } if ($request->filled('notify_follow')) { $request->user()->update(['notify_follow' => (bool) $request->boolean('notify_follow')]); - $request->boolean('notify_follow') == true ? - PushNotificationService::set('follow', $pid) : - PushNotificationService::removeMember('follow', $pid); } if ($request->filled('notify_mention')) { $request->user()->update(['notify_mention' => (bool) $request->boolean('notify_mention')]); - $request->boolean('notify_mention') == true ? - PushNotificationService::set('mention', $pid) : - PushNotificationService::removeMember('mention', $pid); } if ($request->filled('notify_comment')) { $request->user()->update(['notify_comment' => (bool) $request->boolean('notify_comment')]); - $request->boolean('notify_comment') == true ? - PushNotificationService::set('comment', $pid) : - PushNotificationService::removeMember('comment', $pid); - } - - if ($request->boolean('notify_enabled') == false) { - PushNotificationService::removeMemberFromAll($request->user()->profile_id); } $user = $request->user(); diff --git a/app/Services/PushNotificationService.php b/app/Services/PushNotificationService.php index 8acb07acc..bc525d4e4 100644 --- a/app/Services/PushNotificationService.php +++ b/app/Services/PushNotificationService.php @@ -3,121 +3,15 @@ namespace App\Services; use App\User; -use Exception; -use Illuminate\Support\Facades\Cache; -use Illuminate\Support\Facades\Redis; -use Log; -class PushNotificationService -{ - public const ACTIVE_LIST_KEY = 'pf:services:push-notify:active_deliver:'; +class PushNotificationService { public const NOTIFY_TYPES = ['follow', 'like', 'mention', 'comment']; - public const DEEP_CHECK_KEY = 'pf:services:push-notify:deep-check:'; - public const PUSH_GATEWAY_VERSION = '1.0'; - public const LOTTERY_ODDS = 20; - - public const CACHE_LOCK_SECONDS = 10; - - public static function get($list) - { - return Redis::smembers(self::ACTIVE_LIST_KEY.$list); - } - - public static function set($listId, $memberId) - { - if (! in_array($listId, self::NOTIFY_TYPES)) { - return false; - } - $user = User::whereProfileId($memberId)->first(); - if (! $user || $user->status || $user->deleted_at) { - return false; - } - - return Redis::sadd(self::ACTIVE_LIST_KEY.$listId, $memberId); - } - - public static function check($listId, $memberId) - { - return random_int(1, self::LOTTERY_ODDS) === 1 - ? self::isMemberDeepCheck($listId, $memberId) - : self::isMember($listId, $memberId); - } - - public static function isMember($listId, $memberId) - { - try { - return Redis::sismember(self::ACTIVE_LIST_KEY.$listId, $memberId); - } catch (Exception $e) { - return false; - } - } - - public static function isMemberDeepCheck($listId, $memberId) - { - $lock = Cache::lock(self::DEEP_CHECK_KEY.$listId, self::CACHE_LOCK_SECONDS); - - try { - $lock->block(5); - $actualCount = User::whereNull('status')->where('notify_enabled', true)->where('notify_'.$listId, true)->count(); - $cachedCount = self::count($listId); - if ($actualCount != $cachedCount) { - self::warmList($listId); - $user = User::where('notify_enabled', true)->where('profile_id', $memberId)->first(); - - return $user ? (bool) $user->{"notify_{$listId}"} : false; - } else { - return self::isMember($listId, $memberId); - } - } catch (Exception $e) { - Log::error('Failed during deep membership check: '.$e->getMessage()); - - return false; - } finally { - optional($lock)->release(); - } - } - - public static function removeMember($listId, $memberId) - { - return Redis::srem(self::ACTIVE_LIST_KEY.$listId, $memberId); - } - - public static function removeMemberFromAll($memberId) - { - foreach (self::NOTIFY_TYPES as $type) { - self::removeMember($type, $memberId); - } - - return 1; - } - - public static function count($listId) - { - if (! in_array($listId, self::NOTIFY_TYPES)) { - return false; - } - - return Redis::scard(self::ACTIVE_LIST_KEY.$listId); - } - - public static function warmList($listId) - { - if (! in_array($listId, self::NOTIFY_TYPES)) { - return false; - } - $key = self::ACTIVE_LIST_KEY.$listId; - Redis::del($key); - foreach (User::where('notify_'.$listId, true)->cursor() as $acct) { - if ($acct->status || $acct->deleted_at || ! $acct->profile_id || ! $acct->notify_enabled) { - continue; - } - Redis::sadd($key, $acct->profile_id); - } - - return self::count($listId); + public static function check($listId, $memberId) { + $user = User::where('notify_enabled', true)->where('profile_id', $memberId)->first(); + return $user ? (bool) $user->{"notify_{$listId}"} : false; } }