Hello,

I am a bit puzzled by this one and not sure if it is the correct behaviour.

I am using apache solr search and it is returning the results as nids which are then used to filter a view so giving search results in a table. This is of course slows down the return of search results. I am using authcache primarily to speed up this search system and it was working great on older versions (1.4). I changed to 2.0 for other reasons and since then the caching of search results doesn't seem to work for logged in users.

The issue I am seeing is that for anonymous users the search results are being cached. So once the cache is warmed for any particular search the results are returned very quickly.

For logged in users, in the autcache debug message for the search results page I get:

Cache Status: "Caching CANCELLED"
Reason: "Redirecting to http://sitename.com/search/site/searchterm"

If i reload the search results page caching occurs and the page is returned lightning fast. if I repeat the search by submitting the search term again I get the above message and the page age is shown as a couple of seconds.

The fact that the search results page can be cached by reloading says to me the issue is with the redirect but why only with logged in users?

Loving the module in general because it transforms the usability of my Drupal sites.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

znerol’s picture

Reason: "Redirecting to http://sitename.com/search/site/searchterm"

In the source code of apachesolr I see one drupal_goto which potentially causes this redirect. This is around line 500 in apachesolr.module:

/**
 * 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.
 *
 * @param $search_name
 *   The name of the search implementation.
 *
 * @param $querystring
 *   The search query that was issued at the time of failure.
 */
function apachesolr_failure($search_name, $querystring) {
  $fail_rule = variable_get('apachesolr_failure', 'apachesolr:show_error');

  switch ($fail_rule) {
    case 'apachesolr:show_error':
      drupal_set_message(t('Search is temporarily unavailable. If the problem persists, please contact the site administrator.'), 'error');
      break;
    case 'apachesolr:show_no_results':
      // Do nothing.
      break;
    default:
      // If we're failing over to another module make sure the search is available.
      if (module_exists('search')) {
        $search_info = search_get_info();
        if (isset($search_info[$fail_rule])) {
          $search_info = $search_info[$fail_rule];
          drupal_set_message(t("%search_name is not available. Your search is being redirected.", array('%search_name' => $search_name)));
          drupal_goto('search/' . $search_info['path'] . '/' . rawurlencode($querystring));
        }
      }
      // if search is not enabled, break and do nothing
      break;
  }
}

The path search is normally indeed mapped to the core search module. It seems that the solr module somehow encounters an error and then tries to fall back on the core search module. Are there any suspicious entries in your watchdog log?

milton_segretti’s picture

Hello, Thanks for the reply.

Nothing in the logs. Search is working as I expect it to.

In poking around both search module (search.pages.inc - line 45) and apachesolr module (apachesolr_search.module - line 829) I found the below code:

search.pages.inc

<?php
/**
 * @file
 * User page callbacks for the search module.
 */

/**
 * Menu callback; presents the search form and/or search results.
 *
 * @param $module
 *   Search module to use for the search.
 * @param $keys
 *   Keywords to use for the search.
 */
function search_view($module = NULL, $keys = '') {
  $info = FALSE;
  $keys = trim($keys);
  // Also try to pull search keywords out of the $_REQUEST variable to
  // support old GET format of searches for existing links.
  if (!$keys && !empty($_REQUEST['keys'])) {
    $keys = trim($_REQUEST['keys']);
  }

  if (!empty($module)) {
    $active_module_info = search_get_info();
    if (isset($active_module_info[$module])) {
      $info = $active_module_info[$module];
    }
  }

  if (empty($info)) {
    // No path or invalid path: find the default module. Note that if there
    // are no enabled search modules, this function should never be called,
    // since hook_menu() would not have defined any search paths.
    $info = search_get_default_module_info();
    // Redirect from bare /search or an invalid path to the default search path.
    $path = 'search/' . $info['path'];
    if ($keys) {
      $path .= '/' . $keys;
    }
    drupal_goto($path);
  }

  // Default results output is an empty string.
  $results = array('#markup' => '');
  // Process the search form. Note that if there is $_POST data,
  // search_form_submit() will cause a redirect to search/[module path]/[keys],
  // which will get us back to this page callback. In other words, the search
  // form submits with POST but redirects to GET. This way we can keep
  // the search query URL clean as a whistle.
  if (empty($_POST['form_id']) || $_POST['form_id'] != 'search_form') {
    $conditions =  NULL;
    if (isset($info['conditions_callback']) && function_exists($info['conditions_callback'])) {
      // Build an optional array of more search conditions.
      $conditions = call_user_func($info['conditions_callback'], $keys);
    }
    // Only search if there are keywords or non-empty conditions.
    if ($keys || !empty($conditions)) {
      // Log the search keys.
      watchdog('search', 'Searched %type for %keys.', array('%keys' => $keys, '%type' => $info['title']), WATCHDOG_NOTICE, l(t('results'), 'search/' . $info['path'] . '/' . $keys));

      // Collect the search results.
      $results = search_data($keys, $info['module'], $conditions);
    }
  }
  // The form may be altered based on whether the search was run.
  $build['search_form'] = drupal_get_form('search_form', NULL, $keys, $info['module']);
  $build['search_results'] = $results;

  return $build;
}?>

apachesolr_search.module

<?php
/**
 * Executes search depending on the conditions given.
 * See apachesolr_search.pages.inc for another use of this function
 */
function apachesolr_search_search_results($keys = NULL, $conditions = NULL, $search_page = NULL) {
  $params = array();
  $results = array();
  // Process the search form. Note that if there is $_POST data,
  // search_form_submit() will cause a redirect to search/[module path]/[keys],
  // which will get us back to this page callback. In other words, the search
  // form submits with POST but redirects to GET. This way we can keep
  // the search query URL clean as a whistle.
  if (empty($_POST['form_id'])
      || ($_POST['form_id'] != 'apachesolr_search_custom_page_search_form')
      && ($_POST['form_id'] != 'search_form')
      && ($_POST['form_id'] != 'search_block_form') ) {
    // Check input variables
    if (empty($search_page)) {
      $search_page = apachesolr_search_page_load('core_search');
      // Verify if it actually loaded
      if (empty($search_page)) {
        // Something must have been really messed up.
        apachesolr_failure(t('Solr search'), $keys);
        return array();
      }
    }
    if (empty($conditions)) {
      $conditions = apachesolr_search_conditions_default($search_page);
    }?>

Mostly clutching at straws because I don't really know whats going on but I thought the comment "In other words, the search form submits with POST but redirects to GET." was interesting.

znerol’s picture

Could you try and figure out whether you end up in apachesolr_failure somehow? If you don't have a debugger ready, use either drupal_set_message() or watchdog() in order to log a message when apachesolr_failure is entered.

Protip: Install devel and FirePHP and see your watchdog messages scroll by in the Firebug Console during page loads.

milton_segretti’s picture

Hello,

Thanks for the tip.

I can confirm it does not enter apachesolr_failure.

znerol’s picture

Status: Active » Needs review
FileSize
705 bytes

Ok, figured out whats happening. What you see is actually a combination of bugs.

First off, the message reported by Authcache Debug is actually misleading. The reason the search results page is not delivered from the cache for authenticated users actually has nothing to do with the preceding redirect itself (I've opened a separate issue for that #2104653: Authcache Debug shows wrong no-cache reason after redirect).

Rather Authcache 2.x simply prevents that the first request after a POST is delivered from the cache. I see that in your situation this behavior is not desirable. I have to examine some more cases before deciding whether this is a reasonable default behavior #2104661: Rethink automatic preclusion after POST-request. In the meantime you may apply the attached temporary fix, which will disable the mechanism for all pages beneath /search.

HTH

znerol’s picture

Status: Needs review » Fixed

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.