Source for file Balancer.php

Documentation is available at Balancer.php

  1. <?php
  2. /**
  3.  * Copyright (c) 2007-2009, Conduit Internet Technologies, Inc.
  4.  * All rights reserved.
  5.  *
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions are met:
  8.  *
  9.  *  - Redistributions of source code must retain the above copyright notice,
  10.  *    this list of conditions and the following disclaimer.
  11.  *  - Redistributions in binary form must reproduce the above copyright
  12.  *    notice, this list of conditions and the following disclaimer in the
  13.  *    documentation and/or other materials provided with the distribution.
  14.  *  - Neither the name of Conduit Internet Technologies, Inc. nor the names of
  15.  *    its contributors may be used to endorse or promote products derived from
  16.  *    this software without specific prior written permission.
  17.  *
  18.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  19.  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  20.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  21.  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  22.  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  23.  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  24.  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  25.  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  26.  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  27.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  28.  * POSSIBILITY OF SUCH DAMAGE.
  29.  *
  30.  * @copyright Copyright 2007-2009 Conduit Internet Technologies, Inc. (http://conduit-it.com)
  31.  * @license New BSD (http://solr-php-client.googlecode.com/svn/trunk/COPYING)
  32.  *
  33.  * @package Apache
  34.  * @subpackage Solr
  35.  * @author Donovan Jimenez <djimenez@conduit-it.com>, Dan Wolfe
  36.  */
  37.  
  38. // See Issue #1 (http://code.google.com/p/solr-php-client/issues/detail?id=1)
  39. // Doesn't follow typical include path conventions, but is more convenient for users
  40. require_once(dirname(dirname(__FILE__)) '/Service.php');
  41.  
  42. /**
  43.  * Reference Implementation for using multiple Solr services in a distribution. Functionality
  44.  * includes:
  45.  *     routing of read / write operations
  46.  *     failover (on selection) for multiple read servers
  47.  */
  48. {
  49.     protected $_createDocuments = true;
  50.  
  51.     protected $_readableServices = array();
  52.     protected $_writeableServices = array();
  53.  
  54.     protected $_currentReadService = null;
  55.     protected $_currentWriteService = null;
  56.  
  57.     protected $_readPingTimeout = 2;
  58.     protected $_writePingTimeout = 4;
  59.  
  60.     // Configuration for server selection backoff intervals
  61.     protected $_useBackoff = false;        // Set to true to use more resillient write server selection
  62.     protected $_backoffLimit = 600;        // 10 minute default maximum
  63.     protected $_backoffEscalation = 2.0;     // Rate at which to increase backoff period
  64.     protected $_defaultBackoff = 2.0;        // Default backoff interval
  65.  
  66.     /**
  67.      * Escape a value for special query characters such as ':', '(', ')', '*', '?', etc.
  68.      *
  69.      * NOTE: inside a phrase fewer characters need escaped, use {@link Apache_Solr_Service::escapePhrase()} instead
  70.      *
  71.      * @param string $value 
  72.      * @return string 
  73.      */
  74.     static public function escape($value)
  75.     {
  76.         return Apache_Solr_Service::escape($value);
  77.     }
  78.  
  79.     /**
  80.      * Escape a value meant to be contained in a phrase for special query characters
  81.      *
  82.      * @param string $value 
  83.      * @return string 
  84.      */
  85.     static public function escapePhrase($value)
  86.     {
  87.         return Apache_Solr_Service::escapePhrase($value);
  88.     }
  89.  
  90.     /**
  91.      * Convenience function for creating phrase syntax from a value
  92.      *
  93.      * @param string $value 
  94.      * @return string 
  95.      */
  96.     static public function phrase($value)
  97.     {
  98.         return Apache_Solr_Service::phrase($value);
  99.     }
  100.  
  101.     /**
  102.      * Constructor. Takes arrays of read and write service instances or descriptions
  103.      *
  104.      * @param array $readableServices 
  105.      * @param array $writeableServices 
  106.      */
  107.     public function __construct($readableServices array()$writeableServices array())
  108.     {
  109.         //setup readable services
  110.         foreach ($readableServices as $service)
  111.         {
  112.             $this->addReadService($service);
  113.         }
  114.  
  115.         //setup writeable services
  116.         foreach ($writeableServices as $service)
  117.         {
  118.             $this->addWriteService($service);
  119.         }
  120.     }
  121.  
  122.     public function setReadPingTimeout($timeout)
  123.     {
  124.         $this->_readPingTimeout = $timeout;
  125.     }
  126.  
  127.     public function setWritePingTimeout($timeout)
  128.     {
  129.         $this->_writePingTimeout = $timeout;
  130.     }
  131.  
  132.     public function setUseBackoff($enable)
  133.     {
  134.         $this->_useBackoff = $enable;
  135.     }
  136.  
  137.     /**
  138.      * Generates a service ID
  139.      *
  140.      * @param string $host 
  141.      * @param integer $port 
  142.      * @param string $path 
  143.      * @return string 
  144.      */
  145.     protected function _getServiceId($host$port$path)
  146.     {
  147.         return $host ':' $port $path;
  148.     }
  149.  
  150.     /**
  151.      * Adds a service instance or service descriptor (if it is already
  152.      * not added)
  153.      *
  154.      * @param mixed $service 
  155.      *
  156.      * @throws Exception If service descriptor is not valid
  157.      */
  158.     public function addReadService($service)
  159.     {
  160.         if ($service instanceof Apache_Solr_Service)
  161.         {
  162.             $id $this->_getServiceId($service->getHost()$service->getPort()$service->getPath());
  163.  
  164.             $this->_readableServices[$id$service;
  165.         }
  166.         else if (is_array($service))
  167.         {
  168.             if (isset($service['host']&& isset($service['port']&& isset($service['path']))
  169.             {
  170.                 $id $this->_getServiceId((string)$service['host'](int)$service['port'](string)$service['path']);
  171.  
  172.                 $this->_readableServices[$id$service;
  173.             }
  174.             else
  175.             {
  176.                 throw new Exception('A Readable Service description array does not have all required elements of host, port, and path');
  177.             }
  178.         }
  179.     }
  180.  
  181.     /**
  182.      * Removes a service instance or descriptor from the available services
  183.      *
  184.      * @param mixed $service 
  185.      *
  186.      * @throws Exception If service descriptor is not valid
  187.      */
  188.     public function removeReadService($service)
  189.     {
  190.         $id '';
  191.  
  192.         if ($service instanceof Apache_Solr_Service)
  193.         {
  194.             $id $this->_getServiceId($service->getHost()$service->getPort()$service->getPath());
  195.         }
  196.         else if (is_array($service))
  197.         {
  198.             if (isset($service['host']&& isset($service['port']&& isset($service['path']))
  199.             {
  200.                 $id $this->_getServiceId((string)$service['host'](int)$service['port'](string)$service['path']);
  201.             }
  202.             else
  203.             {
  204.                 throw new Exception('A Readable Service description array does not have all required elements of host, port, and path');
  205.             }
  206.         }
  207.         else if (is_string($service))
  208.         {
  209.             $id $service;
  210.         }
  211.  
  212.         if ($id && isset($this->_readableServices[$id]))
  213.         {
  214.             unset($this->_readableServices[$id]);
  215.         }
  216.     }
  217.  
  218.     /**
  219.      * Adds a service instance or service descriptor (if it is already
  220.      * not added)
  221.      *
  222.      * @param mixed $service 
  223.      *
  224.      * @throws Exception If service descriptor is not valid
  225.      */
  226.     public function addWriteService($service)
  227.     {
  228.         if ($service instanceof Apache_Solr_Service)
  229.         {
  230.             $id $this->_getServiceId($service->getHost()$service->getPort()$service->getPath());
  231.  
  232.             $this->_writeableServices[$id$service;
  233.         }
  234.         else if (is_array($service))
  235.         {
  236.             if (isset($service['host']&& isset($service['port']&& isset($service['path']))
  237.             {
  238.                 $id $this->_getServiceId((string)$service['host'](int)$service['port'](string)$service['path']);
  239.  
  240.                 $this->_writeableServices[$id$service;
  241.             }
  242.             else
  243.             {
  244.                 throw new Exception('A Writeable Service description array does not have all required elements of host, port, and path');
  245.             }
  246.         }
  247.     }
  248.  
  249.     /**
  250.      * Removes a service instance or descriptor from the available services
  251.      *
  252.      * @param mixed $service 
  253.      *
  254.      * @throws Exception If service descriptor is not valid
  255.      */
  256.     public function removeWriteService($service)
  257.     {
  258.         $id '';
  259.  
  260.         if ($service instanceof Apache_Solr_Service)
  261.         {
  262.             $id $this->_getServiceId($service->getHost()$service->getPort()$service->getPath());
  263.         }
  264.         else if (is_array($service))
  265.         {
  266.             if (isset($service['host']&& isset($service['port']&& isset($service['path']))
  267.             {
  268.                 $id $this->_getServiceId((string)$service['host'](int)$service['port'](string)$service['path']);
  269.             }
  270.             else
  271.             {
  272.                 throw new Exception('A Readable Service description array does not have all required elements of host, port, and path');
  273.             }
  274.         }
  275.         else if (is_string($service))
  276.         {
  277.             $id $service;
  278.         }
  279.  
  280.         if ($id && isset($this->_writeableServices[$id]))
  281.         {
  282.             unset($this->_writeableServices[$id]);
  283.         }
  284.     }
  285.  
  286.     /**
  287.      * Iterate through available read services and select the first with a ping
  288.      * that satisfies configured timeout restrictions (or the default)
  289.      *
  290.      * @return Apache_Solr_Service 
  291.      *
  292.      * @throws Exception If there are no read services that meet requirements
  293.      */
  294.     protected function _selectReadService($forceSelect false)
  295.     {
  296.         if (!$this->_currentReadService || !isset($this->_readableServices[$this->_currentReadService]|| $forceSelect)
  297.         {
  298.             if ($this->_currentReadService && isset($this->_readableServices[$this->_currentReadService]&& $forceSelect)
  299.             {
  300.                 // we probably had a communication error, ping the current read service, remove it if it times out
  301.                 if ($this->_readableServices[$this->_currentReadService]->ping($this->_readPingTimeout=== false)
  302.                 {
  303.                     $this->removeReadService($this->_currentReadService);
  304.                 }
  305.             }
  306.  
  307.             if (count($this->_readableServices))
  308.             {
  309.                 // select one of the read services at random
  310.                 $ids array_keys($this->_readableServices);
  311.  
  312.                 $id $ids[rand(0count($ids1)];
  313.                 $service $this->_readableServices[$id];
  314.  
  315.                 if (is_array($service))
  316.                 {
  317.                     //convert the array definition to a client object
  318.                     $service new Apache_Solr_Service($service['host']$service['port']$service['path']);
  319.                     $this->_readableServices[$id$service;
  320.                 }
  321.  
  322.                 $service->setCreateDocuments($this->_createDocuments);
  323.                 $this->_currentReadService = $id;
  324.             }
  325.             else
  326.             {
  327.                 throw new Exception('No read services were available');
  328.             }
  329.         }
  330.  
  331.         return $this->_readableServices[$this->_currentReadService];
  332.     }
  333.  
  334.     /**
  335.      * Iterate through available write services and select the first with a ping
  336.      * that satisfies configured timeout restrictions (or the default)
  337.      *
  338.      * @return Apache_Solr_Service 
  339.      *
  340.      * @throws Exception If there are no write services that meet requirements
  341.      */
  342.     protected function _selectWriteService($forceSelect false)
  343.     {
  344.         if($this->_useBackoff)
  345.         {
  346.             return $this->_selectWriteServiceSafe($forceSelect);
  347.         }
  348.  
  349.         if (!$this->_currentWriteService || !isset($this->_writeableServices[$this->_currentWriteService]|| $forceSelect)
  350.         {
  351.             if ($this->_currentWriteService && isset($this->_writeableServices[$this->_currentWriteService]&& $forceSelect)
  352.             {
  353.                 // we probably had a communication error, ping the current read service, remove it if it times out
  354.                 if ($this->_writeableServices[$this->_currentWriteService]->ping($this->_writePingTimeout=== false)
  355.                 {
  356.                     $this->removeWriteService($this->_currentWriteService);
  357.                 }
  358.             }
  359.  
  360.             if (count($this->_writeableServices))
  361.             {
  362.                 // select one of the read services at random
  363.                 $ids array_keys($this->_writeableServices);
  364.  
  365.                 $id $ids[rand(0count($ids1)];
  366.                 $service $this->_writeableServices[$id];
  367.  
  368.                 if (is_array($service))
  369.                 {
  370.                     //convert the array definition to a client object
  371.                     $service new Apache_Solr_Service($service['host']$service['port']$service['path']);
  372.                     $this->_writeableServices[$id$service;
  373.                 }
  374.  
  375.                 $this->_currentWriteService = $id;
  376.             }
  377.             else
  378.             {
  379.                 throw new Exception('No write services were available');
  380.             }
  381.         }
  382.  
  383.         return $this->_writeableServices[$this->_currentWriteService];
  384.     }
  385.  
  386.     /**
  387.      * Iterate through available write services and select the first with a ping
  388.      * that satisfies configured timeout restrictions (or the default).  The
  389.      * timeout period will increase until a connection is made or the limit is
  390.      * reached.   This will allow for increased reliability with heavily loaded
  391.      * server(s).
  392.      *
  393.      * @return Apache_Solr_Service 
  394.      *
  395.      * @throws Exception If there are no write services that meet requirements
  396.      */
  397.  
  398.     protected function _selectWriteServiceSafe($forceSelect false)
  399.     {
  400.         if (!$this->_currentWriteService || !isset($this->_writeableServices[$this->_currentWriteService]|| $forceSelect)
  401.         {
  402.             if (count($this->_writeableServices))
  403.             {
  404.                 $backoff $this->_defaultBackoff;
  405.  
  406.                 do {
  407.                     // select one of the read services at random
  408.                     $ids array_keys($this->_writeableServices);
  409.  
  410.                     $id $ids[rand(0count($ids1)];
  411.                     $service $this->_writeableServices[$id];
  412.  
  413.                     if (is_array($service))
  414.                     {
  415.                         //convert the array definition to a client object
  416.                         $service new Apache_Solr_Service($service['host']$service['port']$service['path']);
  417.                         $this->_writeableServices[$id$service;
  418.                     }
  419.  
  420.                     $this->_currentWriteService = $id;
  421.  
  422.                     $backoff *= $this->_backoffEscalation;
  423.  
  424.                     if($backoff $this->_backoffLimit)
  425.                     {
  426.                         throw new Exception('No write services were available.  All timeouts exceeded.');
  427.                     }
  428.  
  429.                 while($this->_writeableServices[$this->_currentWriteService]->ping($backoff=== false);
  430.             }
  431.             else
  432.             {
  433.                 throw new Exception('No write services were available');
  434.             }
  435.         }
  436.  
  437.         return $this->_writeableServices[$this->_currentWriteService];
  438.     }
  439.  
  440.     public function setCreateDocuments($createDocuments)
  441.     {
  442.         $this->_createDocuments = (bool) $createDocuments;
  443.  
  444.         if ($this->_currentReadService)
  445.         {
  446.             $service $this->_selectReadService();
  447.             $service->setCreateDocuments($createDocuments);
  448.         }
  449.     }
  450.  
  451.     public function getCreateDocuments()
  452.     {
  453.         return $this->_createDocuments;
  454.     }
  455.  
  456.     /**
  457.      * Raw Add Method. Takes a raw post body and sends it to the update service.  Post body
  458.      * should be a complete and well formed "add" xml document.
  459.      *
  460.      * @param string $rawPost 
  461.      * @return Apache_Solr_Response 
  462.      *
  463.      * @throws Exception If an error occurs during the service call
  464.      */
  465.     public function add($rawPost)
  466.     {
  467.         $service $this->_selectWriteService();
  468.  
  469.         do
  470.         {
  471.             try
  472.             {
  473.                 return $service->add($rawPost);
  474.             }
  475.             catch (Exception $e)
  476.             {
  477.                 if ($e->getCode(!= 0//IF NOT COMMUNICATION ERROR
  478.                 {
  479.                     throw $e;
  480.                 }
  481.             }
  482.  
  483.             $service $this->_selectWriteService(true);
  484.         while ($service);
  485.  
  486.         return false;
  487.     }
  488.  
  489.     /**
  490.      * Add a Solr Document to the index
  491.      *
  492.      * @param Apache_Solr_Document $document 
  493.      * @param boolean $allowDups 
  494.      * @param boolean $overwritePending 
  495.      * @param boolean $overwriteCommitted 
  496.      * @return Apache_Solr_Response 
  497.      *
  498.      * @throws Exception If an error occurs during the service call
  499.      */
  500.     public function addDocument(Apache_Solr_Document $document$allowDups false$overwritePending true$overwriteCommitted true)
  501.     {
  502.         $service $this->_selectWriteService();
  503.  
  504.         do
  505.         {
  506.             try
  507.             {
  508.                 return $service->addDocument($document$allowDups$overwritePending$overwriteCommitted);
  509.             }
  510.             catch (Exception $e)
  511.             {
  512.                 if ($e->getCode(!= 0//IF NOT COMMUNICATION ERROR
  513.                 {
  514.                     throw $e;
  515.                 }
  516.             }
  517.  
  518.             $service $this->_selectWriteService(true);
  519.         while ($service);
  520.  
  521.         return false;
  522.     }
  523.  
  524.     /**
  525.      * Add an array of Solr Documents to the index all at once
  526.      *
  527.      * @param array $documents Should be an array of Apache_Solr_Document instances
  528.      * @param boolean $allowDups 
  529.      * @param boolean $overwritePending 
  530.      * @param boolean $overwriteCommitted 
  531.      * @return Apache_Solr_Response 
  532.      *
  533.      * @throws Exception If an error occurs during the service call
  534.      */
  535.     public function addDocuments($documents$allowDups false$overwritePending true$overwriteCommitted true)
  536.     {
  537.         $service $this->_selectWriteService();
  538.  
  539.         do
  540.         {
  541.             try
  542.             {
  543.                 return $service->addDocuments($documents$allowDups$overwritePending$overwriteCommitted);
  544.             }
  545.             catch (Exception $e)
  546.             {
  547.                 if ($e->getCode(!= 0//IF NOT COMMUNICATION ERROR
  548.                 {
  549.                     throw $e;
  550.                 }
  551.             }
  552.  
  553.             $service $this->_selectWriteService(true);
  554.         while ($service);
  555.  
  556.         return false;
  557.     }
  558.  
  559.     /**
  560.      * Send a commit command.  Will be synchronous unless both wait parameters are set
  561.      * to false.
  562.      *
  563.      * @param boolean $waitFlush 
  564.      * @param boolean $waitSearcher 
  565.      * @return Apache_Solr_Response 
  566.      *
  567.      * @throws Exception If an error occurs during the service call
  568.      */
  569.     public function commit($optimize true$waitFlush true$waitSearcher true$timeout 3600)
  570.     {
  571.         $service $this->_selectWriteService();
  572.  
  573.         do
  574.         {
  575.             try
  576.             {
  577.                 return $service->commit($optimize$waitFlush$waitSearcher$timeout);
  578.             }
  579.             catch (Exception $e)
  580.             {
  581.                 if ($e->getCode(!= 0//IF NOT COMMUNICATION ERROR
  582.                 {
  583.                     throw $e;
  584.                 }
  585.             }
  586.  
  587.             $service $this->_selectWriteService(true);
  588.         while ($service);
  589.  
  590.         return false;
  591.     }
  592.  
  593.     /**
  594.      * Raw Delete Method. Takes a raw post body and sends it to the update service. Body should be
  595.      * a complete and well formed "delete" xml document
  596.      *
  597.      * @param string $rawPost 
  598.      * @return Apache_Solr_Response 
  599.      *
  600.      * @throws Exception If an error occurs during the service call
  601.      */
  602.     public function delete($rawPost)
  603.     {
  604.         $service $this->_selectWriteService();
  605.  
  606.         do
  607.         {
  608.             try
  609.             {
  610.                 return $service->delete($rawPost);
  611.             }
  612.             catch (Exception $e)
  613.             {
  614.                 if ($e->getCode(!= 0//IF NOT COMMUNICATION ERROR
  615.                 {
  616.                     throw $e;
  617.                 }
  618.             }
  619.  
  620.             $service $this->_selectWriteService(true);
  621.         while ($service);
  622.  
  623.         return false;
  624.     }
  625.  
  626.     /**
  627.      * Create a delete document based on document ID
  628.      *
  629.      * @param string $id 
  630.      * @param boolean $fromPending 
  631.      * @param boolean $fromCommitted 
  632.      * @return Apache_Solr_Response 
  633.      *
  634.      * @throws Exception If an error occurs during the service call
  635.      */
  636.     public function deleteById($id$fromPending true$fromCommitted true)
  637.     {
  638.         $service $this->_selectWriteService();
  639.  
  640.         do
  641.         {
  642.             try
  643.             {
  644.                 return $service->deleteById($id$fromPending$fromCommitted);
  645.             }
  646.             catch (Exception $e)
  647.             {
  648.                 if ($e->getCode(!= 0//IF NOT COMMUNICATION ERROR
  649.                 {
  650.                     throw $e;
  651.                 }
  652.             }
  653.  
  654.             $service $this->_selectWriteService(true);
  655.         while ($service);
  656.  
  657.         return false;
  658.     }
  659.  
  660.     /**
  661.      * Create a delete document based on a query and submit it
  662.      *
  663.      * @param string $rawQuery 
  664.      * @param boolean $fromPending 
  665.      * @param boolean $fromCommitted 
  666.      * @return Apache_Solr_Response 
  667.      *
  668.      * @throws Exception If an error occurs during the service call
  669.      */
  670.     public function deleteByQuery($rawQuery$fromPending true$fromCommitted true)
  671.     {
  672.         $service $this->_selectWriteService();
  673.  
  674.         do
  675.         {
  676.             try
  677.             {
  678.                 return $service->deleteByQuery($rawQuery$fromPending$fromCommitted);
  679.             }
  680.             catch (Exception $e)
  681.             {
  682.                 if ($e->getCode(!= 0//IF NOT COMMUNICATION ERROR
  683.                 {
  684.                     throw $e;
  685.                 }
  686.             }
  687.  
  688.             $service $this->_selectWriteService(true);
  689.         while ($service);
  690.  
  691.         return false;
  692.     }
  693.  
  694.     /**
  695.      * Send an optimize command.  Will be synchronous unless both wait parameters are set
  696.      * to false.
  697.      *
  698.      * @param boolean $waitFlush 
  699.      * @param boolean $waitSearcher 
  700.      * @return Apache_Solr_Response 
  701.      *
  702.      * @throws Exception If an error occurs during the service call
  703.      */
  704.     public function optimize($waitFlush true$waitSearcher true)
  705.     {
  706.         $service $this->_selectWriteService();
  707.  
  708.         do
  709.         {
  710.             try
  711.             {
  712.                 return $service->optimize($waitFlush$waitSearcher);
  713.             }
  714.             catch (Exception $e)
  715.             {
  716.                 if ($e->getCode(!= 0//IF NOT COMMUNICATION ERROR
  717.                 {
  718.                     throw $e;
  719.                 }
  720.             }
  721.  
  722.             $service $this->_selectWriteService(true);
  723.         while ($service);
  724.  
  725.         return false;
  726.     }
  727.  
  728.     /**
  729.      * Simple Search interface
  730.      *
  731.      * @param string $query The raw query string
  732.      * @param int $offset The starting offset for result documents
  733.      * @param int $limit The maximum number of result documents to return
  734.      * @param array $params key / value pairs for query parameters, use arrays for multivalued parameters
  735.      * @return Apache_Solr_Response 
  736.      *
  737.      * @throws Exception If an error occurs during the service call
  738.      */
  739.     public function search($query$offset 0$limit 10$params array())
  740.     {
  741.         $service $this->_selectReadService();
  742.  
  743.         do
  744.         {
  745.             try
  746.             {
  747.                 return $service->search($query$offset$limit$params);
  748.             }
  749.             catch (Exception $e)
  750.             {
  751.                 if ($e->getCode(!= 0//IF NOT COMMUNICATION ERROR
  752.                 {
  753.                     throw $e;
  754.                 }
  755.             }
  756.  
  757.             $service $this->_selectReadService(true);
  758.         while ($service);
  759.  
  760.         return false;
  761.     }
  762. }

Documentation generated on Wed, 11 Mar 2009 17:34:13 -0400 by phpDocumentor 1.4.2