Version 4.7.23

This commit is contained in:
Neo committed 2025-12-19 16:21:27 -08:00
1 parent 7124a02564
commit 25ddeb65d6
1791 files changed
+76990 -44452

No files matched your search

+41 -7
View File
@@ -10,6 +10,8 @@
namespace IPS;
use function class_exists;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
@@ -29,6 +31,7 @@ class _Redis
/**
* @brief Connections Store
* @var \Redis[]
*/
protected static $connections = array();
@@ -56,6 +59,11 @@ class _Redis
* Writes made
*/
protected static $writes = array();
/**
* @var array
*/
protected static array $connectionAttempts = [];
/**
* Get instance
@@ -158,8 +166,22 @@ class _Redis
{
static::$connections[ $identifier ] = new \Redis;
/* Track connection requests */
if ( ! isset( static::$connectionAttempts[ $identifier ] ) )
{
static::$connectionAttempts[ $identifier ] = 0;
}
/* Prevent too many connection attempts per request */
if( static::$connectionAttempts[ $identifier ] >= \IPS\REDIS_MAX_CONNECTION_ATTEMPTS )
{
throw new \RedisException('CANNOT_CONNECT_TOO_MANY_ATTEMPTS');
}
static::$connectionAttempts[ $identifier ]++;
/* PHP Redis uses many PHP internals to connect, and these can throw ErrorException when they fail but we want a consistent exception */
if( @static::$connections[ $identifier ]->connect( $useConfig['server'], $useConfig['port'], 2 ) === FALSE )
if( @static::$connections[ $identifier ]->connect( $useConfig['server'], $useConfig['port'], 1, '', 500 ) === FALSE ) # Connect with a 1 second timeout, and 500ms between connection attempts
{
unset( static::$connections[ $identifier ] );
throw new \RedisException('CANNOT_CONNECT');
@@ -190,8 +212,8 @@ class _Redis
{
static::$log[ sprintf( '%.4f', microtime(true) ) ] = array( 'redis', "Redis connected (" . $identifier . ' ' . $useConfig['server'] . ")" );
}
if ( \count( static::$connections ) === 1 )
if ( \count( static::$connections ) === 1 ) # Only set the shutdown function if this is the first connection so we don't get multiple shutdown functions
{
register_shutdown_function( function( $object ){
try
@@ -213,7 +235,6 @@ class _Redis
catch( \RedisException $e ){}
}, $this );
}
}
catch( \RedisException $e )
{
@@ -246,7 +267,7 @@ class _Redis
{
if ( method_exists( 'Redis', $method ) )
{
$type = ( \stristr( $method, 'get' ) or \stristr( $method, 'RevRange' ) ) ? 'read' : 'write';
$type = ( \stristr( $method, 'get' ) or \stristr( $method, 'RevRange' ) or $method === 'lRange' ) ? 'read' : 'write';
$return = $this->connection( $type )->$method( ...$args );
if ( $type === 'write' and \count( $args ) )
@@ -467,7 +488,7 @@ class _Redis
if( $decoded === NULL )
{
throw new \RedisException;
throw new \RedisException('DECODE_ERROR');
}
}
else
@@ -486,8 +507,11 @@ class _Redis
*/
public function resetConnection( \RedisException $e = NULL )
{
$message = '';
if ( $e !== NULL )
{
$message = $e->getMessage();
\IPS\Log::debug( $e, 'redis_exception' );
}
@@ -495,7 +519,7 @@ class _Redis
if ( \IPS\REDIS_LOG )
{
static::$log[ microtime() ] = array( 'redis', "Redis connections reset" );
static::$log[ microtime() ] = array( 'redis', "Redis connections reset " . $message );
}
}
@@ -570,4 +594,14 @@ class _Redis
return $return;
}
/**
* A quick and consistent way to see if Redis can be used
*
* @return bool
*/
static public function isEnabled(): bool
{
return class_exists('Redis') and REDIS_ENABLED and REDIS_CONFIG;
}
}