<commit_before><?php
/**
 * Credis_Sentinel
 *
 * Implements the Sentinel API as mentioned on http://redis.io/topics/sentinel.
 * Sentinel is aware of master and slave nodes in a cluster and returns instances of Credis_Client accordingly.
 *
 * The complexity of read/write splitting can also be abstract by calling the createCluster() method which returns a
 * Credis_Cluster object that contains both the master server and a random slave. Credis_Cluster takes care of the
 * read/write splitting
 *
 * @author <NAME> <<EMAIL>>
 * @license http://www.opensource.org/licenses/mit-license.php The MIT License
 * @package Credis_Sentinel
 */
class Credis_Sentinel
{
    /**
     * Contains a client that connects to a Sentinel node.
     * Sentinel uses the same protocol as Redis which makes using Credis_Client convenient.
     * @var Credis_Client
     */
    protected $_client;
    /**
     * Should the master be used for read queries too?
     * @var bool
     */
    protected $_readOnMaster = true;
    /**
     * Contains an active instance of Credis_Cluster per master pool
     * @var Array
     */
    protected $_cluster = array();
    /**
     * Contains an active instance of Credis_Client representing a master
     * @var Array
     */
    protected $_master = array();
    /**
     * Contains an array Credis_Client objects representing all slaves per master pool
     * @var Array
     */
    protected $_slaves = array();
    /**
     * Connect with a Sentinel node. Sentinel will do the master and slave discovery
     * @param Credis_Client $client
     * @param bool $readOnMaster
     */
    public function __construct(Credis_Client $client, $readOnMaster=true)
    {
        if(!$client instanceof Credis_Client){
            throw new CredisException('Sentinel client should be an instance of Credis_Client');
        }
        $client->forceStandalone();
        $this->_client = $client;
        $this->_readOnMaster = (bool)$readOnMaster;
    }
    /**
     * Discover the master node automatically and return an instance of Credis_Client that connects to the master
     * @param string $name
     * @return Credis_Client
     */
    public function createMasterClient($name)
    {
        $master = $this->getMasterAddressByName($name);
        if(!isset($master[0]) || !isset($master[1])){
            throw new CredisException('No master found');
        }
        return new Credis_Client($master[0],$master[1]);
    }
    /**
     * If a Credis_Client object exists for a master, return it. Otherwise create one and return it
     * @param string $name
     * @return Credis_Client
     */
    public function getMasterClient($name)
    {
        if(!isset($this->_master[$name])){
            $this->_master[$name] = $this->createMasterClient($name);
        }
        return $this->_master[$name];
    }
    /**
     * Discover the slave nodes automatically and return an array of Credis_Client objects
     * @param string $name
     * @return Credis_Client[]
     */
    public function createSlaveClients($name)
    {
        $slaves = $this->slaves($name);
        if(!is_array($slaves) && count($slaves) == 0){
            throw new CredisException('No slaves found');
        }
        if($this->_readOnMaster){
            $slaves[] = $this->master($name);
        }
        $workingSlaves = array();
        foreach($slaves as $slave) {
            if(!isset($slave[9])){
                throw new CredisException('Can\' retrieve slave status');
            }
            if(!strstr($slave[9],'s_down') && !strstr($slave[9],'disconnected')) {
                $workingSlaves[] = new Credis_Client($slave[3],$slave[5]);
            }
        }
        return $workingSlaves;
    }
    /**
     * If an array of Credis_Client objects exist for a set of slaves, return them. Otherwise create and return them
     * @param string $name
     * @return Credis_Client[]
     */
    public function getSlaveClients($name)
    {
        if(!isset($this->_slaves[$name])){
            $this->_slaves[$name] = $this->createSlaveClients($name);
        }
        return $this->_slaves[$name];
    }
    /**
     * Returns a Redis cluster object containing a random slave and the master
     * @param string $name
     * @return Credis_Cluster
     */
    public function createCluster($name)
    {
        $clients = array();
        $workingClients = array();
        $master = $this->master($name);
        $clients[] = array('host'=>$master[3],'port'=>$master[5],'master'=>true);
        $slaves = $this->slaves($name);
        foreach($slaves as $slave){
            if(!strstr($slave[9],'s_down') && !strstr($slave[9],'disconnected')) {
                $workingClients[] =  array('host'=>$slave[3],'port'=>$slave[5],'master'=>false);
            }
        }
        if(count($workingClients)>0){
            $clients[] = $workingClients[rand(0,count($workingClients)-1)];
        }
        return new Credis_Cluster($clients,0,$this->_readOnMaster);
    }
    /**
     * If a Credis_Cluster object exists, return it. Otherwise create one and return it.
     * @param string $name
     * @return Credis_Cluster
     */
    public function getCluster($name)
    {
        if(!isset($this->_cluster[$name])){
            $this->_cluster[$name] = $this->createCluster($name);
        }
        return $this->_cluster[$name];
    }
    /**
     * Catch-all method
     * @param string $name
     * @param array $args
     * @return mixed
     */
    public function __call($name, $args)
    {
        array_unshift($args,$name);
        return call_user_func(array($this->_client,'sentinel'),$args);
    }
    /**
     * Return information about all registered master servers
     * @return mixed
     */
    public function masters()
    {
        return $this->_client->sentinel('masters');
    }
    /**
     * Return all information for slaves that are associated with a single master
     * @param string $name
     * @return mixed
     */
    public function slaves($name)
    {
        return $this->_client->sentinel('slaves',$name);
    }
    /**
     * Get the information for a specific master
     * @param string $name
     * @return mixed
     */
    public function master($name)
    {
        return $this->_client->sentinel('master',$name);
    }
    /**
     * Get the hostname and port for a specific master
     * @param string $name
     * @return mixed
     */
    public function getMasterAddressByName($name)
    {
        return $this->_client->sentinel('get-master-addr-by-name',$name);
    }
    /**
     * Check if the Sentinel is still responding
     * @param string $name
     * @return mixed
     */
    public function ping()
    {
        return $this->_client->ping();
    }
    /**
     * Perform an auto-failover which will re-elect another master and make the current master a slave
     * @param string $name
     * @return mixed
     */
    public function failover($name)
    {
        return $this->_client->sentinel('failover',$name);
    }
}<commit_msg>Added flag to select either a random slave or to use all slaves and use hashing.<commit_after><?php
/**
 * Credis_Sentinel
 *
 * Implements the Sentinel API as mentioned on http://redis.io/topics/sentinel.
 * Sentinel is aware of master and slave nodes in a cluster and returns instances of Credis_Client accordingly.
 *
 * The complexity of read/write splitting can also be abstract by calling the createCluster() method which returns a
 * Credis_Cluster object that contains both the master server and a random slave. Credis_Cluster takes care of the
 * read/write splitting
 *
 * @author <NAME> <<EMAIL>>
 * @license http://www.opensource.org/licenses/mit-license.php The MIT License
 * @package Credis_Sentinel
 */
class Credis_Sentinel
{
    /**
     * Contains a client that connects to a Sentinel node.
     * Sentinel uses the same protocol as Redis which makes using Credis_Client convenient.
     * @var Credis_Client
     */
    protected $_client;
    /**
     * Contains an active instance of Credis_Cluster per master pool
     * @var Array
     */
    protected $_cluster = array();
    /**
     * Contains an active instance of Credis_Client representing a master
     * @var Array
     */
    protected $_master = array();
    /**
     * Contains an array Credis_Client objects representing all slaves per master pool
     * @var Array
     */
    protected $_slaves = array();
    /**
     * Connect with a Sentinel node. Sentinel will do the master and slave discovery
     * @param Credis_Client $client
     */
    public function __construct(Credis_Client $client)
    {
        if(!$client instanceof Credis_Client){
            throw new CredisException('Sentinel client should be an instance of Credis_Client');
        }
        $client->forceStandalone();
        $this->_client = $client;
    }
    /**
     * Discover the master node automatically and return an instance of Credis_Client that connects to the master
     * @param string $name
     * @return Credis_Client
     */
    public function createMasterClient($name)
    {
        $master = $this->getMasterAddressByName($name);
        if(!isset($master[0]) || !isset($master[1])){
            throw new CredisException('No master found');
        }
        return new Credis_Client($master[0],$master[1]);
    }
    /**
     * If a Credis_Client object exists for a master, return it. Otherwise create one and return it
     * @param string $name
     * @return Credis_Client
     */
    public function getMasterClient($name)
    {
        if(!isset($this->_master[$name])){
            $this->_master[$name] = $this->createMasterClient($name);
        }
        return $this->_master[$name];
    }
    /**
     * Discover the slave nodes automatically and return an array of Credis_Client objects
     * @param string $name
     * @return Credis_Client[]
     */
    public function createSlaveClients($name)
    {
        $slaves = $this->slaves($name);
        if(!is_array($slaves) && count($slaves) == 0){
            throw new CredisException('No slaves found');
        }
        if($this->_readOnMaster){
            $slaves[] = $this->master($name);
        }
        $workingSlaves = array();
        foreach($slaves as $slave) {
            if(!isset($slave[9])){
                throw new CredisException('Can\' retrieve slave status');
            }
            if(!strstr($slave[9],'s_down') && !strstr($slave[9],'disconnected')) {
                $workingSlaves[] = new Credis_Client($slave[3],$slave[5]);
            }
        }
        return $workingSlaves;
    }
    /**
     * If an array of Credis_Client objects exist for a set of slaves, return them. Otherwise create and return them
     * @param string $name
     * @return Credis_Client[]
     */
    public function getSlaveClients($name)
    {
        if(!isset($this->_slaves[$name])){
            $this->_slaves[$name] = $this->createSlaveClients($name);
        }
        return $this->_slaves[$name];
    }
    /**
     * Returns a Redis cluster object containing a random slave and the master
     * When $selectRandomSlave is true, only one random slave is passed.
     * When $selectRandomSlave is false, all clients are passed and hashing is applied in Credis_Cluster
     * When $readOnMaster is true, the master server will also be used for read commands.
     * @param string $name
     * @param bool $selectRandomSlave
     * @param bool $readOnMaster
     * @return Credis_Cluster
     */
    public function createCluster($name, $selectRandomSlave=true, $readOnMaster=true)
    {
        $clients = array();
        $workingClients = array();
        $master = $this->master($name);
        if(strstr($master[9],'s_down') || strstr($master[9],'disconnected')) {
            throw new CredisException('The master is down');
        }
        $clients[] = array('host'=>$master[3],'port'=>$master[5],'master'=>true);
        $slaves = $this->slaves($name);
        foreach($slaves as $slave){
            if(!strstr($slave[9],'s_down') && !strstr($slave[9],'disconnected')) {
                $workingClients[] =  array('host'=>$slave[3],'port'=>$slave[5],'master'=>false);
            }
        }
        if(count($workingClients)>0){
            if($selectRandomSlave){
                $clients[] = $workingClients[rand(0,count($workingClients)-1)];
            } else {
                $clients[] = $workingClients;
            }
        }
        return new Credis_Cluster($clients,0,$readOnMaster);
    }
    /**
     * If a Credis_Cluster object exists, return it. Otherwise create one and return it.
     * @param string $name
     * @param bool $selectRandomSlave
     * @param bool $readOnMaster
     * @return Credis_Cluster
     */
    public function getCluster($name, $selectRandomSlave=true, $readOnMaster=true)
    {
        if(!isset($this->_cluster[$name])){
            $this->_cluster[$name] = $this->createCluster($name, $selectRandomSlave, $readOnMaster);
        }
        return $this->_cluster[$name];
    }
    /**
     * Catch-all method
     * @param string $name
     * @param array $args
     * @return mixed
     */
    public function __call($name, $args)
    {
        array_unshift($args,$name);
        return call_user_func(array($this->_client,'sentinel'),$args);
    }
    /**
     * Return information about all registered master servers
     * @return mixed
     */
    public function masters()
    {
        return $this->_client->sentinel('masters');
    }
    /**
     * Return all information for slaves that are associated with a single master
     * @param string $name
     * @return mixed
     */
    public function slaves($name)
    {
        return $this->_client->sentinel('slaves',$name);
    }
    /**
     * Get the information for a specific master
     * @param string $name
     * @return mixed
     */
    public function master($name)
    {
        return $this->_client->sentinel('master',$name);
    }
    /**
     * Get the hostname and port for a specific master
     * @param string $name
     * @return mixed
     */
    public function getMasterAddressByName($name)
    {
        return $this->_client->sentinel('get-master-addr-by-name',$name);
    }
    /**
     * Check if the Sentinel is still responding
     * @param string $name
     * @return mixed
     */
    public function ping()
    {
        return $this->_client->ping();
    }
    /**
     * Perform an auto-failover which will re-elect another master and make the current master a slave
     * @param string $name
     * @return mixed
     */
    public function failover($name)
    {
        return $this->_client->sentinel('failover',$name);
    }
}
{'fraction_non_alphanumeric': 0.12399618892064788, 'fraction_numerical': 0.0028583095140873828, 'mean_word_length': 2.4584608143092495, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 91, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2674354', 'n_tokens_mistral': 4225, 'n_tokens_neox': 4107, 'n_words': 1161}