Skip to content
This repository was archived by the owner on Feb 7, 2024. It is now read-only.

Commit ee8681a

Browse files
committed
Use a RedisLock to avoid race conditions.
1 parent 0f4928f commit ee8681a

File tree

1 file changed

+30
-17
lines changed

1 file changed

+30
-17
lines changed

src/Statistics/Logger/RedisStatisticsLogger.php

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use BeyondCode\LaravelWebSockets\Apps\App;
66
use BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver;
77
use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager;
8+
use Illuminate\Cache\RedisLock;
89
use Illuminate\Support\Facades\Cache;
910

1011
class RedisStatisticsLogger implements StatisticsLogger
@@ -115,24 +116,26 @@ public function disconnection($appId)
115116
*/
116117
public function save()
117118
{
118-
foreach ($this->redis->smembers('laravel-websockets:apps') as $appId) {
119-
if (! $statistic = $this->redis->hgetall($this->getHash($appId))) {
120-
continue;
119+
$this->lock()->get(function () {
120+
foreach ($this->redis->smembers('laravel-websockets:apps') as $appId) {
121+
if (! $statistic = $this->redis->hgetall($this->getHash($appId))) {
122+
continue;
123+
}
124+
125+
$this->driver::create([
126+
'app_id' => $appId,
127+
'peak_connection_count' => $statistic['peak_connection_count'] ?? 0,
128+
'websocket_message_count' => $statistic['websocket_message_count'] ?? 0,
129+
'api_message_count' => $statistic['api_message_count'] ?? 0,
130+
]);
131+
132+
$currentConnectionCount = $this->channelManager->getConnectionCount($appId);
133+
134+
$currentConnectionCount === 0
135+
? $this->resetAppTraces($appId)
136+
: $this->resetStatistics($appId, $currentConnectionCount);
121137
}
122-
123-
$this->driver::create([
124-
'app_id' => $appId,
125-
'peak_connection_count' => $statistic['peak_connection_count'] ?? 0,
126-
'websocket_message_count' => $statistic['websocket_message_count'] ?? 0,
127-
'api_message_count' => $statistic['api_message_count'] ?? 0,
128-
]);
129-
130-
$currentConnectionCount = $this->channelManager->getConnectionCount($appId);
131-
132-
$currentConnectionCount === 0
133-
? $this->resetAppTraces($appId)
134-
: $this->resetStatistics($appId, $currentConnectionCount);
135-
}
138+
});
136139
}
137140

138141
/**
@@ -190,4 +193,14 @@ protected function getHash($appId): string
190193
{
191194
return "laravel-websockets:app:{$appId}";
192195
}
196+
197+
/**
198+
* Get a new RedisLock instance to avoid race conditions.
199+
*
200+
* @return \Illuminate\Cache\CacheLock
201+
*/
202+
protected function lock()
203+
{
204+
return new RedisLock($this->redis, 'laravel-websockets:lock', 0);
205+
}
193206
}

0 commit comments

Comments
 (0)