-
Notifications
You must be signed in to change notification settings - Fork 7
/
functions.php
129 lines (105 loc) · 3.43 KB
/
functions.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
<?php
namespace WP_Predis;
use Predis\Client as PredisClient;
use Exception;
require_once( dirname( __FILE__ ) . '/class-wp-predis-decorator.php' );
function add_filters( $add_filter_fn = 'add_filter' ) {
$add_filter_fn( 'wp_redis_check_client_dependencies_callback', 'WP_Predis\check_client_dependencies_callback' );
$add_filter_fn( 'wp_redis_prepare_client_connection_callback', 'WP_Predis\prepare_client_connection_callback' );
$add_filter_fn( 'wp_redis_perform_client_connection_callback', 'WP_Predis\perform_client_connection_callback', 10, 3 );
$add_filter_fn( 'wp_redis_retry_exception_messages', 'WP_Predis\append_error_messages' );
$add_filter_fn( 'shutdown', 'WP_Predis\shutdown', 10, 0 );
}
function check_client_dependencies() {
if ( ! class_exists( 'Predis\Client' ) ) {
return 'Warning! The Predis\Client class is unavailable, which is required by WP Redis Predis.';
}
return true;
}
function prepare_client_connection( $args ) {
// TODO $connection_details['timeout']
// TODO $connection_details['retry_interval']
$params = build_params( $args );
$options = build_options( $args );
$client = new PredisClient( $params, $options );
$redis = new Decorator( $client );
return $redis;
}
function perform_client_connection( $redis, $settings, $keys_methods = array()) {
try {
// we ignore $keys_methods because both auth and database selection are
// handled in Predis/Client instantiation.
$redis->connect();
} catch ( Exception $e ) {
// Predis throws an Exception when it fails a server call.
// To prevent WordPress from fataling, we catch the Exception.
// TODO Perhaps we catch and rethrow? or return instance of
// WP_Error?
throw new Exception( $e->getMessage(), $e->getCode(), $e );
}
return true;
}
function build_params( $args ) {
$scheme = 'tcp';
$hostKey = 'host';
$isTLS = isset( $args['ssl'] ) && is_array( $args['ssl'] );
if ( $isTLS ) {
$scheme = 'tls';
} elseif ( null === $args['port'] ) {
// If port is null, it's a socket connection
$scheme = 'unix';
$hostKey = 'path';
}
$params = array(
'scheme' => $scheme,
$hostKey => $args['host'],
);
if ( 'unix' !== $scheme ) {
$params['port'] = $args['port'];
}
if ( $isTLS ) {
$params['ssl'] = $args['ssl'];
}
return $params;
}
function build_options( $args ) {
$options = array(
'exceptions' => true,
'parameters' => array(
'password' => isset( $args['auth'] ) ? $args['auth'] : null,
'database' => isset( $args['database'] ) ? $args['database'] : null,
'persistent' => isset( $args['persistent'] ) ? $args['persistent'] : null,
),
);
return $options;
}
function append_error_messages( $errors ) {
return array(
'/^Connection refused/',
);
}
function check_client_dependencies_callback() {
return 'WP_Predis\check_client_dependencies';
}
function prepare_client_connection_callback() {
return 'WP_Predis\prepare_client_connection';
}
function perform_client_connection_callback() {
return 'WP_Predis\perform_client_connection';
}
/**
* Shutdown hook.
*
* Runs during shutdown, even if the shutdown happened due
* to a fatal error/exception.
*/
function shutdown() {
global $wp_object_cache;
// Disconnect a Redis socket if the shutdown happened with a fatal.
// Prevents a persistent socket from being corrupted if the error
// happens while reading from Redis.
$error = error_get_last();
if ( $error && $error['type'] === E_ERROR && isset( $wp_object_cache->redis ) ) {
$wp_object_cache->redis->disconnect();
}
}