Update StoryIndexService, improve predis + phpredis support

pull/6139/head
Daniel Supernault 3 months ago
parent fcb1ed5826
commit 564d8d1091
No known key found for this signature in database
GPG Key ID: 23740873EE6F76A1

@ -34,6 +34,71 @@ class StoryIndexService
return 'story:rebuilding';
}
/**
* Safely convert Redis result to integer, handling both predis and phpredis
*/
private function redisToInt($value): int
{
if (is_int($value)) {
return $value;
}
if (is_string($value) || is_numeric($value)) {
return (int) $value;
}
// Handle phpredis object returns
if (is_object($value) && method_exists($value, '__toString')) {
return (int) $value->__toString();
}
// Fallback for unexpected types
return 0;
}
/**
* Safely convert Redis result to boolean
*/
private function redisToBool($value): bool
{
if (is_bool($value)) {
return $value;
}
if (is_int($value)) {
return $value > 0;
}
if (is_string($value)) {
return $value === '1' || strtolower($value) === 'true';
}
// Handle phpredis object returns
if (is_object($value) && method_exists($value, '__toString')) {
$str = $value->__toString();
return $str === '1' || strtolower($str) === 'true';
}
return false;
}
/**
* Safely execute Redis commands that return integers
*/
private function redisInt(callable $command): int
{
return $this->redisToInt($command());
}
/**
* Safely execute Redis commands that return booleans
*/
private function redisBool(callable $command): bool
{
return $this->redisToBool($command());
}
public function indexStory($story): void
{
if (! $story->active) {
@ -95,7 +160,7 @@ class StoryIndexService
$pipe->del($this->storyKey($sid));
});
if ((int) Redis::zcard($this->authorKey($aid)) === 0) {
if ($this->redisInt(fn () => Redis::zcard($this->authorKey($aid))) === 0) {
Redis::srem('story:active_authors', $aid);
}
}
@ -109,7 +174,7 @@ class StoryIndexService
$secondsUntilExpiry = $expiresAt->getTimestamp() - time();
$ttl = max(1, $secondsUntilExpiry);
$currentTtl = Redis::ttl($key);
$currentTtl = $this->redisInt(fn () => Redis::ttl($key));
if ($currentTtl < 0) {
$currentTtl = 0;
}
@ -233,7 +298,7 @@ class StoryIndexService
private function ensureStoryCacheHealth(): bool
{
$activeCount = (int) Redis::scard('story:active_authors');
$activeCount = $this->redisInt(fn () => Redis::scard('story:active_authors'));
if ($activeCount > 0) {
return true;
@ -277,8 +342,8 @@ class StoryIndexService
$this->hydrateFollowingFromSql($viewerId);
}
$followingCount = (int) Redis::scard("following:{$pid}");
$activeCount = (int) Redis::scard('story:active_authors');
$followingCount = $this->redisInt(fn () => Redis::scard("following:{$pid}"));
$activeCount = $this->redisInt(fn () => Redis::scard('story:active_authors'));
$authorIds = [];
@ -293,19 +358,19 @@ class StoryIndexService
if (is_array($results) && count($results) === count($active)) {
foreach ($active as $i => $aid) {
if ($results[$i] ?? false) {
if ($this->redisToBool($results[$i] ?? false)) {
$authorIds[] = $aid;
}
}
} else {
$authorIds = array_filter($active, fn ($aid) => Redis::sismember("following:{$pid}", $aid));
$authorIds = array_filter($active, fn ($aid) => $this->redisBool(fn () => Redis::sismember("following:{$pid}", $aid)));
}
}
} else {
$authorIds = Redis::sinter("following:{$pid}", 'story:active_authors');
}
if (Redis::zcard($this->authorKey($pid)) > 0) {
if ($this->redisInt(fn () => Redis::zcard($this->authorKey($pid))) > 0) {
array_unshift($authorIds, $pid);
$authorIds = array_values(array_unique($authorIds));
}

Loading…
Cancel
Save