Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like RedisBagOStuff often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use RedisBagOStuff, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 28 | class RedisBagOStuff extends BagOStuff { |
||
| 29 | /** @var RedisConnectionPool */ |
||
| 30 | protected $redisPool; |
||
| 31 | /** @var array List of server names */ |
||
| 32 | protected $servers; |
||
| 33 | /** @var array Map of (tag => server name) */ |
||
| 34 | protected $serverTagMap; |
||
| 35 | /** @var bool */ |
||
| 36 | protected $automaticFailover; |
||
| 37 | |||
| 38 | /** |
||
| 39 | * Construct a RedisBagOStuff object. Parameters are: |
||
| 40 | * |
||
| 41 | * - servers: An array of server names. A server name may be a hostname, |
||
| 42 | * a hostname/port combination or the absolute path of a UNIX socket. |
||
| 43 | * If a hostname is specified but no port, the standard port number |
||
| 44 | * 6379 will be used. Arrays keys can be used to specify the tag to |
||
| 45 | * hash on in place of the host/port. Required. |
||
| 46 | * |
||
| 47 | * - connectTimeout: The timeout for new connections, in seconds. Optional, |
||
| 48 | * default is 1 second. |
||
| 49 | * |
||
| 50 | * - persistent: Set this to true to allow connections to persist across |
||
| 51 | * multiple web requests. False by default. |
||
| 52 | * |
||
| 53 | * - password: The authentication password, will be sent to Redis in |
||
| 54 | * clear text. Optional, if it is unspecified, no AUTH command will be |
||
| 55 | * sent. |
||
| 56 | * |
||
| 57 | * - automaticFailover: If this is false, then each key will be mapped to |
||
| 58 | * a single server, and if that server is down, any requests for that key |
||
| 59 | * will fail. If this is true, a connection failure will cause the client |
||
| 60 | * to immediately try the next server in the list (as determined by a |
||
| 61 | * consistent hashing algorithm). True by default. This has the |
||
| 62 | * potential to create consistency issues if a server is slow enough to |
||
| 63 | * flap, for example if it is in swap death. |
||
| 64 | * @param array $params |
||
| 65 | */ |
||
| 66 | function __construct( $params ) { |
||
| 89 | |||
| 90 | View Code Duplication | protected function doGet( $key, $flags = 0 ) { |
|
| 106 | |||
| 107 | View Code Duplication | public function set( $key, $value, $expiry = 0, $flags = 0 ) { |
|
| 128 | |||
| 129 | public function delete( $key ) { |
||
| 146 | |||
| 147 | public function getMulti( array $keys, $flags = 0 ) { |
||
| 185 | |||
| 186 | /** |
||
| 187 | * @param array $data |
||
| 188 | * @param int $expiry |
||
| 189 | * @return bool |
||
| 190 | */ |
||
| 191 | public function setMulti( array $data, $expiry = 0 ) { |
||
| 234 | |||
| 235 | View Code Duplication | public function add( $key, $value, $expiry = 0 ) { |
|
| 259 | |||
| 260 | /** |
||
| 261 | * Non-atomic implementation of incr(). |
||
| 262 | * |
||
| 263 | * Probably all callers actually want incr() to atomically initialise |
||
| 264 | * values to zero if they don't exist, as provided by the Redis INCR |
||
| 265 | * command. But we are constrained by the memcached-like interface to |
||
| 266 | * return null in that case. Once the key exists, further increments are |
||
| 267 | * atomic. |
||
| 268 | * @param string $key Key to increase |
||
| 269 | * @param int $value Value to add to $key (Default 1) |
||
| 270 | * @return int|bool New value or false on failure |
||
| 271 | */ |
||
| 272 | View Code Duplication | public function incr( $key, $value = 1 ) { |
|
| 291 | |||
| 292 | View Code Duplication | public function changeTTL( $key, $expiry = 0 ) { |
|
| 309 | |||
| 310 | public function modifySimpleRelayEvent( array $event ) { |
||
| 317 | |||
| 318 | /** |
||
| 319 | * @param mixed $data |
||
| 320 | * @return string |
||
| 321 | */ |
||
| 322 | protected function serialize( $data ) { |
||
| 327 | |||
| 328 | /** |
||
| 329 | * @param string $data |
||
| 330 | * @return mixed |
||
| 331 | */ |
||
| 332 | protected function unserialize( $data ) { |
||
| 336 | |||
| 337 | /** |
||
| 338 | * Get a Redis object with a connection suitable for fetching the specified key |
||
| 339 | * @param string $key |
||
| 340 | * @return array (server, RedisConnRef) or (false, false) |
||
| 341 | */ |
||
| 342 | protected function getConnection( $key ) { |
||
| 387 | |||
| 388 | /** |
||
| 389 | * Check the master link status of a Redis server that is configured as a replica DB. |
||
| 390 | * @param RedisConnRef $conn |
||
| 391 | * @return string|null Master link status (either 'up' or 'down'), or null |
||
| 392 | * if the server is not a replica DB. |
||
| 393 | */ |
||
| 394 | protected function getMasterLinkStatus( RedisConnRef $conn ) { |
||
| 400 | |||
| 401 | /** |
||
| 402 | * Log a fatal error |
||
| 403 | * @param string $msg |
||
| 404 | */ |
||
| 405 | protected function logError( $msg ) { |
||
| 408 | |||
| 409 | /** |
||
| 410 | * The redis extension throws an exception in response to various read, write |
||
| 411 | * and protocol errors. Sometimes it also closes the connection, sometimes |
||
| 412 | * not. The safest response for us is to explicitly destroy the connection |
||
| 413 | * object and let it be reopened during the next request. |
||
| 414 | * @param RedisConnRef $conn |
||
| 415 | * @param Exception $e |
||
| 416 | */ |
||
| 417 | protected function handleException( RedisConnRef $conn, $e ) { |
||
| 421 | |||
| 422 | /** |
||
| 423 | * Send information about a single request to the debug log |
||
| 424 | * @param string $method |
||
| 425 | * @param string $key |
||
| 426 | * @param string $server |
||
| 427 | * @param bool $result |
||
| 428 | */ |
||
| 429 | public function logRequest( $method, $key, $server, $result ) { |
||
| 433 | } |
||
| 434 |
Scrutinizer analyzes your
composer.json/composer.lockfile if available to determine the classes, and functions that are defined by your dependencies.It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.