-
Notifications
You must be signed in to change notification settings - Fork 0
/
redis_flush.module
99 lines (80 loc) · 2.73 KB
/
redis_flush.module
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
<?php
/**
* @file
* {@inheritdoc}
*/
use Drupal\redis\ClientFactory;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Site\Settings;
/**
* Implements hook_cache_flush().
*
* Empties all Drupal cache from a Redis DB instance upon cache flush
* action (ie. when running `drush cache-rebuild`). Supports several
* flush modes. @see README.md for more details.
*/
function redis_cache_flush() {
// Ensure that we are connected to Redis and can get a reference to.
// the active client before proceeding.
if (!ClientFactory::hasClient() ||
!$redis = ClientFactory::getClient()) {
return;
}
$redis_flush_settings = Settings::get('redis_flush');
$redis_connection_settings = Settings::get('redis.connection');
// If a redis connection is not configured, abort.
if (empty($redis_connection_settings)) {
return;
}
if (empty($redis_flush_settings)) {
$redis_flush_settings = [];
} elseif ($redis_flush_settings['mode'] === false) {
return;
}
// Default settings if none were provided in settings.php.
$redis_flush_settings += [
'mode' => 'bin',
'skip_bins' => [],
];
$redis_base_index = !isset($redis_connection_settings['base']) ? 0 : $redis_connection_settings['base'];
// Allow for non-default (0) instance DB to be flushed.
if (isset($redis_base_index) &&
is_numeric($redis_base_index) &&
$redis_base_index >= 0 &&
// Redis instance supports up to 16 DBs.
$redis_base_index <= 16) {
$redis->select($redis_base_index);
}
// @see README for more details on the flush modes
switch ($redis_flush_settings['mode']) {
case 'develop':
// Using flushDb() instead of flushAll() since the Redis Module only
// supports 1 database for Drupal cache at this time.
$redis->flushDb();
break;
case 'bin':
$redis->setOption(Redis::OPT_SCAN, Redis::SCAN_RETRY);
$flush_keys = [];
$cache_prefix = Settings::get('cache_prefix');
// checksum, lock, and queue are not cache bins so we do not need.
// any logic to skip them.
foreach (Cache::getBins() as $bin => $cache_interface) {
// Reset the SCAN iterator for each bin.
$iterator = NULL;
$keys = [];
if (get_class($cache_interface) !== 'Drupal\redis\Cache\PhpRedis' ||
in_array($bin, $redis_flush_settings['skip_bins'])) {
continue;
}
// Use SCAN to locate the keys for this bin.
// (https://redis.io/commands/scan).
while ($arr_keys = $redis->scan($iterator, "${cache_prefix}:${bin}:*")) {
foreach ($arr_keys as $str_key) {
$keys[] = $str_key;
}
}
// Delete the keys found for this bin.
$redis->delete($keys);
}
}
}