Merge pull request #633 from beyondcode/fix/fix-stale-data

[fix] Fix stale data
This commit is contained in:
rennokki 2020-12-08 00:41:19 +02:00 committed by GitHub
commit de7e358550
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 96 additions and 4 deletions

View File

@ -66,4 +66,13 @@ interface StatisticsCollector
* @return PromiseInterface[\BeyondCode\LaravelWebSockets\Statistics\Statistic|null]
*/
public function getAppStatistics($appId): PromiseInterface;
/**
* Remove all app traces from the database if no connections have been set
* in the meanwhile since last save.
*
* @param string|int $appId
* @return void
*/
public function resetAppTraces($appId);
}

View File

@ -96,6 +96,12 @@ class MemoryCollector implements StatisticsCollector
continue;
}
if ($statistic->shouldHaveTracesRemoved()) {
$this->resetAppTraces($appId);
continue;
}
$this->createRecord($statistic, $appId);
$this->channelManager
@ -142,6 +148,18 @@ class MemoryCollector implements StatisticsCollector
);
}
/**
* Remove all app traces from the database if no connections have been set
* in the meanwhile since last save.
*
* @param string|int $appId
* @return void
*/
public function resetAppTraces($appId)
{
unset($this->statistics[$appId]);
}
/**
* Find or create a defined statistic for an app.
*

View File

@ -170,6 +170,10 @@ class RedisCollector extends MemoryCollector
$appId, Helpers::redisListToArray($list)
);
if ($statistic->shouldHaveTracesRemoved()) {
return $this->resetAppTraces($appId);
}
$this->createRecord($statistic, $appId);
$this->channelManager
@ -265,7 +269,7 @@ class RedisCollector extends MemoryCollector
->getPublishClient()
->hset(
$this->channelManager->getRedisKey($appId, null, ['stats']),
'peak_connections_count', $currentConnectionCount
'peak_connections_count', max(0, $currentConnectionCount)
);
$this->channelManager
@ -292,6 +296,8 @@ class RedisCollector extends MemoryCollector
*/
public function resetAppTraces($appId)
{
parent::resetAppTraces($appId);
$this->channelManager
->getPublishClient()
->hdel(

View File

@ -178,11 +178,23 @@ class Statistic
public function reset(int $currentConnectionsCount)
{
$this->currentConnectionsCount = $currentConnectionsCount;
$this->peakConnectionsCount = $currentConnectionsCount;
$this->peakConnectionsCount = max(0, $currentConnectionsCount);
$this->webSocketMessagesCount = 0;
$this->apiMessagesCount = 0;
}
/**
* Check if the current statistic entry is empty. This means
* that the statistic entry can be easily deleted if no activity
* occured for a while.
*
* @return bool
*/
public function shouldHaveTracesRemoved(): bool
{
return $this->currentConnectionsCount === 0 && $this->peakConnectionsCount === 0;
}
/**
* Transform the statistic to array.
*

View File

@ -16,6 +16,21 @@ class StatisticsStoreTest extends TestCase
$this->assertEquals('2', $records[0]['peak_connections_count']);
$this->assertEquals('2', $records[0]['websocket_messages_count']);
$this->assertEquals('0', $records[0]['api_messages_count']);
$this->pusherServer->onClose($rick);
$this->pusherServer->onClose($morty);
$this->statisticsCollector->save();
$this->assertCount(2, $records = $this->statisticsStore->getRecords());
$this->assertEquals('2', $records[1]['peak_connections_count']);
$this->statisticsCollector->save();
// The last one should not generate any more records
// since the current state is empty.
$this->assertCount(2, $records = $this->statisticsStore->getRecords());
}
public function test_store_statistics_on_private_channel()
@ -30,19 +45,51 @@ class StatisticsStoreTest extends TestCase
$this->assertEquals('2', $records[0]['peak_connections_count']);
$this->assertEquals('2', $records[0]['websocket_messages_count']);
$this->assertEquals('0', $records[0]['api_messages_count']);
$this->pusherServer->onClose($rick);
$this->pusherServer->onClose($morty);
$this->statisticsCollector->save();
$this->assertCount(2, $records = $this->statisticsStore->getRecords());
$this->assertEquals('2', $records[1]['peak_connections_count']);
$this->statisticsCollector->save();
// The last one should not generate any more records
// since the current state is empty.
$this->assertCount(2, $records = $this->statisticsStore->getRecords());
}
public function test_store_statistics_on_presence_channel()
{
$rick = $this->newPresenceConnection('presence-channel', ['user_id' => 1]);
$morty = $this->newPresenceConnection('presence-channel', ['user_id' => 2]);
$pickleRick = $this->newPresenceConnection('presence-channel', ['user_id' => 1]);
$this->statisticsCollector->save();
$this->assertCount(1, $records = $this->statisticsStore->getRecords());
$this->assertEquals('2', $records[0]['peak_connections_count']);
$this->assertEquals('2', $records[0]['websocket_messages_count']);
$this->assertEquals('3', $records[0]['peak_connections_count']);
$this->assertEquals('3', $records[0]['websocket_messages_count']);
$this->assertEquals('0', $records[0]['api_messages_count']);
$this->pusherServer->onClose($rick);
$this->pusherServer->onClose($morty);
$this->pusherServer->onClose($pickleRick);
$this->statisticsCollector->save();
$this->assertCount(2, $records = $this->statisticsStore->getRecords());
$this->assertEquals('3', $records[1]['peak_connections_count']);
$this->statisticsCollector->save();
// The last one should not generate any more records
// since the current state is empty.
$this->assertCount(2, $records = $this->statisticsStore->getRecords());
}
}