Skip to content

Commit 19e0833

Browse files
committed
Keep only 100 notifications per user.
1 parent 355eeb5 commit 19e0833

File tree

2 files changed

+92
-2
lines changed

2 files changed

+92
-2
lines changed

src/MessageHandler/TopBarNotificationHandler.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ class TopBarNotificationHandler
1414
private $redis;
1515
private $liveUpdates;
1616

17+
public const MAX_NOTIFICATIONS = 100;
18+
1719
public function __construct(
1820
Redis $redis,
1921
LiveUpdates $liveUpdates)
@@ -37,8 +39,15 @@ public function __invoke(TopBarNotification $message)
3739
'timestamp' => (new \DateTime())->getTimestamp()
3840
];
3941

40-
$this->redis->lpush($listKey, $uuid);
41-
$this->redis->hset($hashKey, $uuid, json_encode($payload));
42+
$this->redis->lPush($listKey, $uuid);
43+
$this->redis->hSet($hashKey, $uuid, json_encode($payload));
44+
45+
$length = $this->redis->lLen($listKey);
46+
if ($length > self::MAX_NOTIFICATIONS) {
47+
$itemsToRemove = $this->redis->lRange($listKey, self::MAX_NOTIFICATIONS, $length - 1);
48+
$this->redis->lTrim($listKey, 0, self::MAX_NOTIFICATIONS - 1);
49+
$this->redis->hDel($hashKey, ...$itemsToRemove);
50+
}
4251

4352
$notificationsPayload = [
4453
'name' => 'notifications',
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<?php
2+
3+
namespace Tests\AppBundle\MessageHandler;
4+
5+
use AppBundle\Message\TopBarNotification;
6+
use AppBundle\MessageHandler\TopBarNotificationHandler;
7+
use AppBundle\Service\LiveUpdates;
8+
use Prophecy\PhpUnit\ProphecyTrait;
9+
use Ramsey\Uuid\Uuid;
10+
use Redis;
11+
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
12+
13+
class TopBarNotificationHandlerFunctionalTest extends KernelTestCase
14+
{
15+
private $redis;
16+
private $liveUpdates;
17+
18+
use ProphecyTrait;
19+
20+
public function setUp(): void
21+
{
22+
parent::setUp();
23+
24+
self::bootKernel();
25+
26+
$this->redis = self::getContainer()->get(Redis::class);
27+
$this->liveUpdates = $this->prophesize(LiveUpdates::class);
28+
}
29+
30+
public function tearDown(): void
31+
{
32+
$this->redis->del('user:bob:notifications');
33+
$this->redis->del('user:bob:notifications_data');
34+
35+
parent::tearDown();
36+
}
37+
38+
public function testNotificationsLimit()
39+
{
40+
$handler = new TopBarNotificationHandler(
41+
$this->redis,
42+
$this->liveUpdates->reveal()
43+
);
44+
45+
for ($i = 0; $i < 500; $i++) {
46+
$message = new TopBarNotification(['bob'], 'Lorem ipsum');
47+
call_user_func_array($handler, [$message]);
48+
}
49+
50+
$this->assertEquals(TopBarNotificationHandler::MAX_NOTIFICATIONS, $this->redis->llen('user:bob:notifications'));
51+
$this->assertEquals(TopBarNotificationHandler::MAX_NOTIFICATIONS, $this->redis->hlen('user:bob:notifications_data'));
52+
}
53+
54+
public function testNotificationsLimitWithExisting()
55+
{
56+
$handler = new TopBarNotificationHandler(
57+
$this->redis,
58+
$this->liveUpdates->reveal()
59+
);
60+
61+
for ($i = 0; $i < 500; $i++) {
62+
63+
$uuid = Uuid::uuid4()->toString();
64+
65+
$payload = [
66+
'id' => $uuid,
67+
'message' => 'Lorem ipsum',
68+
'timestamp' => (new \DateTime())->getTimestamp()
69+
];
70+
71+
$this->redis->lPush('user:bob:notifications', $uuid);
72+
$this->redis->hSet('user:bob:notifications_data', $uuid, json_encode($payload));
73+
}
74+
75+
$message = new TopBarNotification(['bob'], 'Lorem ipsum');
76+
call_user_func_array($handler, [$message]);
77+
78+
$this->assertEquals(TopBarNotificationHandler::MAX_NOTIFICATIONS, $this->redis->llen('user:bob:notifications'));
79+
$this->assertEquals(TopBarNotificationHandler::MAX_NOTIFICATIONS, $this->redis->hlen('user:bob:notifications_data'));
80+
}
81+
}

0 commit comments

Comments
 (0)