redis-8.x-1.x-dev/src/Client/PhpRedisFactory.php

src/Client/PhpRedisFactory.php
<?php

namespace Drupal\redis\Client;

use Drupal\redis\ClientInterface;

/**
 * PhpRedis client factory.
 */
class PhpRedisFactory implements RedisClientFactoryInterface {

  /**
   * {@inheritdoc}
   */
  public function isAvailable(): bool {
    return class_exists(\Redis::class);
  }

  /**
   * {@inheritdoc}
   */
  public function getClient(array $settings): ClientInterface {
    $redis = new \Redis();

    $host = $settings['host'];
    $port = $settings['port'];

    // Sentinel mode, get the real master.
    if (is_array($host)) {
      $ip_host = $this->askForMaster($redis, $settings);
      if (is_array($ip_host)) {
        [$host, $port] = $ip_host;
      }
    }

    if (!empty($settings['persistent'])) {
      $redis->pconnect($host, $port);
    }
    else {
      $redis->connect($host, $port);
    }

    if (isset($settings['password'])) {
      $redis->auth($settings['password']);
    }

    if (isset($settings['base'])) {
      $redis->select($settings['base']);
    }

    // Do not allow PhpRedis serialize itself data, we are going to do it
    // ourself. This will ensure less memory footprint on Redis size when
    // we will attempt to store small values.
    $redis->setOption(\Redis::OPT_SERIALIZER, \Redis::SERIALIZER_NONE);

    return new PhpRedis($redis);
  }

  /**
   * {@inheritdoc}
   */
  public function getName(): string {
    return 'PhpRedis';
  }

  /**
   * Connect to sentinels to get Redis master instance.
   *
   * Just asking one sentinels after another until given the master location.
   * More info about this mode at https://redis.io/topics/sentinel.
   *
   * @param \Redis $client
   *   The PhpRedis client.
   * @param array $settings
   *   The configuration settings.
   *
   * @return mixed
   *   An array with ip & port of the Master instance or NULL.
   */
  protected function askForMaster(\Redis $client, array $settings) {

    assert(is_array($settings['host']));

    $ip_port = NULL;
    $settings += ['instance' => NULL];

    if ($settings['instance']) {
      foreach ($settings['host'] as $sentinel) {
        [$host, $port] = explode(':', $sentinel);
        // Prevent fatal PHP errors when one of the sentinels is down.
        set_error_handler(function () {
          return TRUE;
        });
        // 0.5s timeout.
        $success = $client->connect($host, $port, 0.5);
        restore_error_handler();

        if (!$success) {
          continue;
        }

        if (isset($settings['password'])) {
          $client->auth($settings['password']);
        }

        if ($client->isConnected()) {
          $ip_port = $client->rawcommand('SENTINEL', 'get-master-addr-by-name', $settings['instance']);
          if ($ip_port) {
            break;
          }
        }
        $client->close();
      }
    }
    return $ip_port;
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc