Index: CHANGELOG.txt
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/apachesolr/CHANGELOG.txt,v
retrieving revision 1.1.2.154
diff -u -p -r1.1.2.154 CHANGELOG.txt
--- CHANGELOG.txt 9 Jan 2010 00:50:43 -0000 1.1.2.154
+++ CHANGELOG.txt 27 Jan 2010 16:23:41 -0000
@@ -5,6 +5,7 @@ Apache Solr Search Integration x.x-x.x,
Apache Solr Search Integration 6.x-1.x, xxxx-xx-xx
------------------------------
+#267831 by claudiu.cristea: Load balancer implementation.
#679522 by pwolanin, Add gettableFiles to solr admin intefrace config.
Apache Solr Search Integration 6.x-1.0-RC5, 2010-01-04
Index: Drupal_Apache_Solr_Service.php
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/apachesolr/Drupal_Apache_Solr_Service.php,v
retrieving revision 1.1.2.26
diff -u -p -r1.1.2.26 Drupal_Apache_Solr_Service.php
--- Drupal_Apache_Solr_Service.php 26 Dec 2009 17:12:38 -0000 1.1.2.26
+++ Drupal_Apache_Solr_Service.php 27 Jan 2010 16:23:41 -0000
@@ -33,7 +33,8 @@ class Drupal_Apache_Solr_Service extends
* @return
* (float) seconds taken to ping the server, FALSE if timeout occurs.
*/
- public function ping($timeout = 2) {
+ public function ping() {
+ $timeout = func_get_arg(0);
$start = microtime(TRUE);
if ($timeout <= 0.0) {
Index: Drupal_Apache_Solr_Service_Balancer.php
===================================================================
RCS file: Drupal_Apache_Solr_Service_Balancer.php
diff -N Drupal_Apache_Solr_Service_Balancer.php
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Drupal_Apache_Solr_Service_Balancer.php 27 Jan 2010 16:23:41 -0000
@@ -0,0 +1,107 @@
+_selectWriteService();
+
+ do {
+ try {
+ return $service->getStatsSummary();
+ }
+ catch (Exception $e) {
+ if ($e->getCode() != 0) { //IF NOT COMMUNICATION ERROR
+ throw $e;
+ }
+ }
+ $service = $this->_selectWriteService(TRUE);
+ } while ($service);
+
+ return FALSE;
+ }
+
+ /**
+ * Clear cached Solr data.
+ */
+ public function clearCache() {
+ foreach ($this->_readableServices as $service) {
+ @$service->clearCache;
+ }
+ foreach ($this->_writableServices as $service) {
+ @$service->clearCache;
+ }
+ }
+
+ /**
+ * Get meta-data about the index.
+ */
+ public function getLuke($num_terms = 0) {
+ $service = $this->_selectWriteService();
+
+ do {
+ try {
+ return $service->getLuke($num_terms);
+ }
+ catch (Exception $e) {
+ if ($e->getCode() != 0) { //IF NOT COMMUNICATION ERROR
+ throw $e;
+ }
+ }
+ $service = $this->_selectWriteService(TRUE);
+ } while ($service);
+
+ return FALSE;
+ }
+ /**
+ * Get just the field meta-data about the index.
+ */
+ public function getFields($num_terms = 0) {
+ return $this->getLuke($num_terms)->fields;
+ }
+
+ /**
+ * For some reasons this was not implemented in Balancer.
+ */
+ public function deleteByMultipleIds($ids, $fromPending = true, $fromCommitted = true, $timeout = 3600) {
+ $service = $this->_selectWriteService();
+
+ do {
+ try {
+ return $service->deleteByMultipleIds($ids, $fromPending = true, $fromCommitted = true, $timeout = 3600);
+ }
+ catch (Exception $e) {
+ if ($e->getCode() != 0) { //IF NOT COMMUNICATION ERROR
+ throw $e;
+ }
+ }
+ $service = $this->_selectWriteService(TRUE);
+ } while ($service);
+
+ return FALSE;
+ }
+
+ /**
+ * Check if an index or query server is vailable.
+ */
+ public function ping($timeout = 2, $service_type) {
+ $service = $service_type == 'index' ? $this->_selectWriteService() : $this->_selectReadService();
+
+ do {
+ try {
+ return $service->ping($timeout);
+ }
+ catch (Exception $e) {
+ if ($e->getCode() != 0) { //IF NOT COMMUNICATION ERROR
+ throw $e;
+ }
+ }
+ $service = $service_type == 'index' ? $this->_selectWriteService(TRUE) : $this->_selectReadService(TRUE);
+ } while ($service);
+
+ return FALSE;
+ }
+}
Index: apachesolr.admin.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/apachesolr/apachesolr.admin.inc,v
retrieving revision 1.1.2.46
diff -u -p -r1.1.2.46 apachesolr.admin.inc
--- apachesolr.admin.inc 27 Dec 2009 16:47:37 -0000 1.1.2.46
+++ apachesolr.admin.inc 27 Jan 2010 16:23:41 -0000
@@ -22,27 +22,6 @@ function apachesolr_settings() {
}
}
- $form['apachesolr_host'] = array(
- '#type' => 'textfield',
- '#title' => t('Solr host name'),
- '#default_value' => variable_get('apachesolr_host', 'localhost'),
- '#description' => t('Host name of your Solr server, e.g. localhost or example.com.'),
- '#required' => TRUE,
- );
- $form['apachesolr_port'] = array(
- '#type' => 'textfield',
- '#title' => t('Solr port'),
- '#default_value' => variable_get('apachesolr_port', '8983'),
- '#description' => t('Port on which the Solr server listens. The Jetty example server is 8983, while Tomcat is 8080 by default.'),
- '#required' => TRUE,
- );
- $form['apachesolr_path'] = array(
- '#type' => 'textfield',
- '#title' => t('Solr path'),
- '#default_value' => variable_get('apachesolr_path', '/solr'),
- '#description' => t('Path that identifies the Solr request handler to be used.'),
- );
-
$numbers = drupal_map_assoc(array(1, 5, 10, 20, 50, 100, 200));
$form['apachesolr_cron_limit'] = array(
'#type' => 'select',
@@ -110,6 +89,239 @@ function apachesolr_settings_validate($f
}
/**
+ * Callback for configuring Solr servers.
+ */
+function apachesolr_settings_servers($server_id = NULL, $delete = NULL) {
+ $output = '';
+ $servers = variable_get('apachesolr_servers', array());
+ if ($delete == 'delete' && isset($servers[$server_id])) {
+ return drupal_get_form('apachesolr_settings_servers_delete', $server_id);
+ }
+ $server_id = is_null($server_id) ? 'add' : $server_id;
+ if (count($servers)) {
+ $header = array('#', t('Server name'), t('Host name'), t('Port'), t('Path'), t('Query server'), t('Index server'), t('Status'), array('data' => t('Operations'), 'colspan' => 2));
+ $rows = array();
+ foreach ($servers as $delta => $server) {
+ $ping = FALSE;
+ try {
+ $solr = apachesolr_get_server($server['host'], $server['port'], $server['path']);
+ $ping = @$solr->ping(variable_get('apachesolr_ping_timeout', 4));
+ // If there is no $solr object, there is no server available, so don't continue.
+ if (!$ping) {
+ throw new Exception(t('No Solr instance available for !host:!port/!path', array('!host' => $server['host'], '!port' => $server['port'], '!path' => ltrim($server['path'], '/'))));
+ }
+ }
+ catch (Exception $e) {
+ watchdog('Apache Solr', nl2br(check_plain($e->getMessage())), NULL, WATCHDOG_ERROR);
+ }
+
+ $row = array($delta, $server['name'], $server['host'], $server['port'], $server['path'], $server['query'] ? t('Yes') : t('No'), $server['index'] ? t('Yes') : t('No'), $ping ? t('Successfully contacted') : t('Cannot be contacted!'), l(t('modify'), 'admin/settings/apachesolr/servers/'. $delta), l(t('delete'), 'admin/settings/apachesolr/servers/'. $delta .'/delete'));
+ if ($server_id == (string)$delta) {
+ $rows[] = array(
+ 'data' => $row,
+ 'class' => 'apachesolr-servers-active-server',
+ );
+ }
+ else {
+ $rows[] = $row;
+ }
+ }
+ $element = array(
+ '#type' => 'fieldset',
+ '#title' => t('Solr servers currentlly configured on this site'),
+ '#collapsible' => TRUE,
+ '#collpased' => FALSE,
+ '#value' => theme('table', $header, $rows) . ($server_id != 'add' ? '
'. print_r(array($server), TRUE) .''); + + // @todo: Delete old variables + // variable_del('apachesolr_host'); + // variable_del('apachesolr_port'); + // variable_del('apachesolr_path'); + // $ret[] = array('success' => TRUE, 'query' => 'Drupal variables: "apachesolr_host", "apachesolr_port", "apachesolr_path" were deleted.'); + + return $ret; +} Index: apachesolr.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/apachesolr/apachesolr.module,v retrieving revision 1.1.2.12.2.182 diff -u -p -r1.1.2.12.2.182 apachesolr.module --- apachesolr.module 2 Jan 2010 13:48:14 -0000 1.1.2.12.2.182 +++ apachesolr.module 27 Jan 2010 16:23:41 -0000 @@ -30,6 +30,30 @@ function apachesolr_menu() { 'file' => 'apachesolr.admin.inc', 'type' => MENU_DEFAULT_LOCAL_TASK, ); + $items['admin/settings/apachesolr/servers'] = array( + 'title' => 'Solr Servers', + 'page callback' => 'apachesolr_settings_servers', + 'weight' => -9, + 'access arguments' => array('administer search'), + 'file' => 'apachesolr.admin.inc', + 'type' => MENU_LOCAL_TASK, + ); + $items['admin/settings/apachesolr/servers/%apachesolr_server'] = array( + 'title' => 'Solr Servers', + 'page callback' => 'apachesolr_settings_servers', + 'page arguments' => array(4), + 'access arguments' => array('administer search'), + 'file' => 'apachesolr.admin.inc', + 'type' => MENU_CALLBACK, + ); + $items['admin/settings/apachesolr/servers/%apachesolr_server/delete'] = array( + 'title' => 'Solr Servers', + 'page callback' => 'apachesolr_settings_servers', + 'page arguments' => array(4, 'delete'), + 'access arguments' => array('administer search'), + 'file' => 'apachesolr.admin.inc', + 'type' => MENU_CALLBACK, + ); $items['admin/settings/apachesolr/enabled-filters'] = array( 'title' => 'Enabled filters', 'page callback' => 'drupal_get_form', @@ -92,6 +116,20 @@ function apachesolr_menu() { } /** + * Menu loader for %apachesolr_server. + * + * @param $server_id + * Argument passed. + * + * @return + * The server informations ID of FALSE. + */ +function apachesolr_server_load($server_id = NULL) { + $servers = variable_get('apachesolr_servers', array()); + return isset($servers[$server_id]) ? $servers[$server_id] : FALSE; +} + +/** * Determines Apache Solr's behavior when searching causes an exception (e.g. Solr isn't available.) * Depending on the admin settings, possibly redirect to Drupal's core search. * @@ -1113,24 +1151,56 @@ function apachesolr_has_searched($search } /** - * Factory method for solr singleton object. Structure allows for an arbitrary - * number of solr objects to be used based on the host, port, path combination. - * Get an instance like this: - * $solr = apachesolr_get_solr(); + * Method used to obtain the Solr load balancer object */ -function apachesolr_get_solr($host = NULL, $port = NULL, $path = NULL) { - static $solr_cache; +function apachesolr_get_solr() { + static $solr; + $servers = variable_get('apachesolr_servers', array()); + if (!isset($solr)) { + // We use only one Solr server (this may be the main usage of this module) + // Do not load the entire Balancer API use only a single Solr object. + if (count($servers) == 1) { + $solr = apachesolr_get_server($servers[0]['host'], $servers[0]['port'], $servers[0]['path']); + } + // More than one Solr servers are configured on the site so prepare the Solr + // object as a Balancer object. + else { + $query_services = $index_services = array(); + foreach ($servers as $delta => $server) { - if (empty($host)) { - $host = variable_get('apachesolr_host', 'localhost'); - } - if (empty($port)) { - $port = variable_get('apachesolr_port', '8983'); - } - if (empty($path)) { - $path = variable_get('apachesolr_path', '/solr'); + $service = ($server['query'] || $server['index']) ? apachesolr_get_server($server['host'], $server['port'], $server['path']) : FALSE; + + // Collect query services (AKA readable services). + if ($server['query'] && $service) { + $query_services[] = $service; + } + + // Collect index services (AKA writable services). + if ($server['index'] && $service) { + $index_services[] = $service; + } + } + + include_once(drupal_get_path('module', 'apachesolr') .'/Drupal_Apache_Solr_Service_Balancer.php'); + try { + $solr = new Drupal_Apache_Solr_Service_Balancer($query_services, $index_services); + } + catch (Exception $e) { + watchdog('Apache Solr', nl2br(check_plain($e->getMessage())), NULL, WATCHDOG_ERROR); + return; + } + } } + return $solr; +} + +/** + * Method used to obtain a single Solr object. A clone of old apachesolr_get_solr() function but arguments are mandatory. + */ +function apachesolr_get_server($host, $port, $path) { + static $solr_cache; + if (empty($solr_cache[$host][$port][$path])) { list($module, $filepath, $class) = variable_get('apachesolr_service_class', array('apachesolr', 'Drupal_Apache_Solr_Service.php', 'Drupal_Apache_Solr_Service')); include_once(drupal_get_path('module', $module) .'/'. $filepath);