Use a RedisLock to avoid race conditions.
This commit is contained in:
parent
0f4928f93a
commit
ee8681a459
|
|
@ -5,6 +5,7 @@ namespace BeyondCode\LaravelWebSockets\Statistics\Logger;
|
||||||
use BeyondCode\LaravelWebSockets\Apps\App;
|
use BeyondCode\LaravelWebSockets\Apps\App;
|
||||||
use BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver;
|
use BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver;
|
||||||
use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager;
|
use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager;
|
||||||
|
use Illuminate\Cache\RedisLock;
|
||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
|
||||||
class RedisStatisticsLogger implements StatisticsLogger
|
class RedisStatisticsLogger implements StatisticsLogger
|
||||||
|
|
@ -115,24 +116,26 @@ class RedisStatisticsLogger implements StatisticsLogger
|
||||||
*/
|
*/
|
||||||
public function save()
|
public function save()
|
||||||
{
|
{
|
||||||
foreach ($this->redis->smembers('laravel-websockets:apps') as $appId) {
|
$this->lock()->get(function () {
|
||||||
if (! $statistic = $this->redis->hgetall($this->getHash($appId))) {
|
foreach ($this->redis->smembers('laravel-websockets:apps') as $appId) {
|
||||||
continue;
|
if (! $statistic = $this->redis->hgetall($this->getHash($appId))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->driver::create([
|
||||||
|
'app_id' => $appId,
|
||||||
|
'peak_connection_count' => $statistic['peak_connection_count'] ?? 0,
|
||||||
|
'websocket_message_count' => $statistic['websocket_message_count'] ?? 0,
|
||||||
|
'api_message_count' => $statistic['api_message_count'] ?? 0,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$currentConnectionCount = $this->channelManager->getConnectionCount($appId);
|
||||||
|
|
||||||
|
$currentConnectionCount === 0
|
||||||
|
? $this->resetAppTraces($appId)
|
||||||
|
: $this->resetStatistics($appId, $currentConnectionCount);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
$this->driver::create([
|
|
||||||
'app_id' => $appId,
|
|
||||||
'peak_connection_count' => $statistic['peak_connection_count'] ?? 0,
|
|
||||||
'websocket_message_count' => $statistic['websocket_message_count'] ?? 0,
|
|
||||||
'api_message_count' => $statistic['api_message_count'] ?? 0,
|
|
||||||
]);
|
|
||||||
|
|
||||||
$currentConnectionCount = $this->channelManager->getConnectionCount($appId);
|
|
||||||
|
|
||||||
$currentConnectionCount === 0
|
|
||||||
? $this->resetAppTraces($appId)
|
|
||||||
: $this->resetStatistics($appId, $currentConnectionCount);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -190,4 +193,14 @@ class RedisStatisticsLogger implements StatisticsLogger
|
||||||
{
|
{
|
||||||
return "laravel-websockets:app:{$appId}";
|
return "laravel-websockets:app:{$appId}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a new RedisLock instance to avoid race conditions.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Cache\CacheLock
|
||||||
|
*/
|
||||||
|
protected function lock()
|
||||||
|
{
|
||||||
|
return new RedisLock($this->redis, 'laravel-websockets:lock', 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue