Skip to content

Commit e8ea8a9

Browse files
authored
Support persistent connections via WP_REDIS_PERSISTENT (#633)
1 parent f3f33a4 commit e8ea8a9

3 files changed

Lines changed: 40 additions & 5 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ The Redis Object Cache plugin comes with vast set of configuration options. If y
5353
| `WP_REDIS_SSL_CONTEXT` | `[]` | TLS connection options for `tls` or `rediss` scheme |
5454
| `WP_REDIS_FLUSH_TIMEOUT` | `5` | Experimental. The timeout in seconds when flushing |
5555
| `WP_REDIS_RETRY_INTERVAL` | | The number of milliseconds between retries (PhpRedis only) |
56+
| `WP_REDIS_PERSISTENT` | `false` | Whether to persistent connections. Optionally, accepts non-empty connection identifier string. |
5657
| `WP_REDIS_GLOBAL_GROUPS` | `[]` | Additional groups that are considered global on multisite networks |
5758
| `WP_REDIS_CHART_COLOR` | | Override admin metrics chart color using a hex value (`#RGB` or `#RRGGBB`) |
5859
| `WP_REDIS_METRICS_MAX_TIME` | `3600` | The maximum number of seconds metrics should be stored |

includes/diagnostics.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
$info['Timeout'] = $wp_object_cache->diagnostics['timeout'] ?? false;
6363
$info['Read Timeout'] = $wp_object_cache->diagnostics['read_timeout'] ?? false;
6464
$info['Retry Interval'] = $wp_object_cache->diagnostics['retry_interval'] ?? false;
65+
$info['Persistent'] = $wp_object_cache->diagnostics['persistent'] ?? false;
6566
}
6667

6768
$constants = [
@@ -76,6 +77,7 @@
7677
'WP_REDIS_TIMEOUT',
7778
'WP_REDIS_READ_TIMEOUT',
7879
'WP_REDIS_RETRY_INTERVAL',
80+
'WP_REDIS_PERSISTENT',
7981
'WP_REDIS_SERVERS',
8082
'WP_REDIS_CLUSTER',
8183
'WP_REDIS_SHARDS',

includes/object-cache.php

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,7 @@ protected function build_parameters() {
640640
'timeout',
641641
'read_timeout',
642642
'retry_interval',
643+
'persistent',
643644
];
644645

645646
foreach ( $settings as $setting ) {
@@ -657,10 +658,35 @@ protected function build_parameters() {
657658
$this->diagnostics[ 'timeout' ] = $parameters[ 'timeout' ];
658659
$this->diagnostics[ 'read_timeout' ] = $parameters[ 'read_timeout' ];
659660
$this->diagnostics[ 'retry_interval' ] = $parameters[ 'retry_interval' ];
661+
$this->diagnostics[ 'persistent' ] = $parameters[ 'persistent' ];
660662

661663
return $parameters;
662664
}
663665

666+
/**
667+
* Build the identifier persistent connections are pooled by.
668+
*
669+
* `WP_REDIS_PERSISTENT` carries both answers: any truthy value turns persistence on, and a
670+
* non-empty string additionally names the pool. Anything else falls back to the default.
671+
*
672+
* PhpRedis, Relay and Credis keep one persistent connection per host, port and identifier.
673+
* Whatever is applied *after* connecting is part of that connection's state and therefore
674+
* has to be part of the identifier: `select()` is only called for a non-zero database, so
675+
* two sites sharing a pool would otherwise silently inherit whichever database the other
676+
* one selected last. That is why the default carries the database, and why an identifier
677+
* given by hand is the caller's to keep distinct.
678+
*
679+
* @param array $parameters Connection parameters built by the `build_parameters` method.
680+
* @return string
681+
*/
682+
protected function build_persistent_id( $parameters ) {
683+
if ( is_string( $parameters['persistent'] ) && $parameters['persistent'] !== '' ) {
684+
return $parameters['persistent'];
685+
}
686+
687+
return sprintf( 'wp-db%s', $parameters['database'] );
688+
}
689+
664690
/**
665691
* Connect to Redis using the PhpRedis (PECL) extension.
666692
*
@@ -709,7 +735,7 @@ protected function connect_using_phpredis( $parameters ) {
709735
'host' => $parameters['host'],
710736
'port' => $parameters['port'],
711737
'timeout' => $parameters['timeout'],
712-
'',
738+
'persistent_id' => $parameters['persistent'] ? $this->build_persistent_id( $parameters ) : '',
713739
'retry_interval' => (int) $parameters['retry_interval'],
714740
];
715741

@@ -734,7 +760,10 @@ protected function connect_using_phpredis( $parameters ) {
734760
$args['port'] = -1;
735761
}
736762

737-
call_user_func_array( [ $this->redis, 'connect' ], array_values( $args ) );
763+
call_user_func_array(
764+
[ $this->redis, $parameters['persistent'] ? 'pconnect' : 'connect' ],
765+
array_values( $args )
766+
);
738767

739768
if ( isset( $parameters['password'] ) ) {
740769
$args['password'] = $parameters['password'];
@@ -779,7 +808,7 @@ protected function connect_using_relay( $parameters ) {
779808
'host' => $parameters['host'],
780809
'port' => $parameters['port'],
781810
'timeout' => $parameters['timeout'],
782-
'',
811+
'persistent_id' => $parameters['persistent'] ? $this->build_persistent_id( $parameters ) : '',
783812
'retry_interval' => (int) $parameters['retry_interval'],
784813
];
785814

@@ -802,7 +831,10 @@ protected function connect_using_relay( $parameters ) {
802831
$args['port'] = -1;
803832
}
804833

805-
call_user_func_array( [ $this->redis, 'connect' ], array_values( $args ) );
834+
call_user_func_array(
835+
[ $this->redis, $parameters['persistent'] ? 'pconnect' : 'connect' ],
836+
array_values( $args )
837+
);
806838

807839
if ( isset( $parameters['password'] ) ) {
808840
$args['password'] = $parameters['password'];
@@ -1049,7 +1081,7 @@ protected function connect_using_credis( $parameters ) {
10491081
'host' => $parameters['scheme'] === 'unix' ? $parameters['path'] : $parameters['host'],
10501082
'port' => $parameters['port'],
10511083
'timeout' => $parameters['timeout'],
1052-
'persistent' => '',
1084+
'persistent' => $parameters['persistent'] ? $this->build_persistent_id( $parameters ) : '',
10531085
'database' => $parameters['database'],
10541086
'password' => isset( $parameters['password'] ) ? $parameters['password'] : null,
10551087
];

0 commit comments

Comments
 (0)