You are here

function search_api_server_tasks_check in Search API 7

Checks for pending tasks on one or all enabled search servers.

Parameters

SearchApiServer|null $server: (optional) The server whose tasks should be checked. If not given, the tasks for all enabled servers are checked.

Return value

bool TRUE if all tasks (for the specific server, if $server was given) were executed successfully, or if there were no tasks. FALSE if there are still pending tasks.

4 calls to search_api_server_tasks_check()
search_api_cron in ./search_api.module
Implements hook_cron().
search_api_execute_pending_tasks_batch in ./search_api.module
Executes pending server tasks as part of a batch operation.
search_api_index_specific_items in ./search_api.module
Indexes the specified items on the given index.
search_api_search_api_server_update in ./search_api.module
Implements hook_search_api_server_update().

File

./search_api.module, line 1418
Provides a flexible framework for implementing search services.

Code

function search_api_server_tasks_check(SearchApiServer $server = NULL) {
  $select = db_select('search_api_task', 't')
    ->fields('t')
    ->condition('t.type', array(
    'addIndex',
    'fieldsUpdated',
    'removeIndex',
    'deleteItems',
  ));
  if ($server) {
    $select
      ->condition('t.server_id', $server->machine_name);
  }
  else {
    $select
      ->innerJoin('search_api_server', 's', 't.server_id = s.machine_name AND s.enabled = 1');

    // By ordering by the server, we can later just load them when we reach them
    // while looping through the tasks. It is very unlikely there will be tasks
    // for more than one or two servers, so a *_load_multiple() probably
    // wouldn't bring any significant advantages, but complicate the code.
    $select
      ->orderBy('t.server_id');
  }

  // Store a count query for later checking whether all tasks were processed
  // successfully.
  $count_query = $select
    ->countQuery();

  // Sometimes the order of tasks might be important, so make sure to order by
  // the task ID (which should be in order of insertion).
  $select
    ->orderBy('t.id');

  // Only retrieve and execute 100 tasks at once, to avoid running out of memory
  // or time. We just can't do anything else until all tasks have been resolved,
  // but at least we shouldn't crash sites, or keep piling up tasks, that way.
  $select
    ->range(0, 100);
  $tasks = $select
    ->execute();
  $executed_tasks = array();
  foreach ($tasks as $task) {
    if (!$server || $server->machine_name != $task->server_id) {
      $server = search_api_server_load($task->server_id);
      if (!$server) {
        continue;
      }
    }
    switch ($task->type) {
      case 'addIndex':
        $index = search_api_index_load($task->index_id);
        if ($index) {
          $server
            ->addIndex($index);
        }
        break;
      case 'fieldsUpdated':
        $index = search_api_index_load($task->index_id);
        if ($index) {
          if ($task->data) {
            $index->original = unserialize($task->data);
          }
          $server
            ->fieldsUpdated($index);
        }
        break;
      case 'removeIndex':
        $index = search_api_index_load($task->index_id);
        if ($index) {
          $server
            ->removeIndex($index ? $index : $task->index_id);
        }
        break;
      case 'deleteItems':
        $ids = $task->data ? unserialize($task->data) : 'all';
        $index = $task->index_id ? search_api_index_load($task->index_id) : NULL;

        // Since a failed load returns (for stupid menu handler reasons) FALSE,
        // not NULL, we have to make doubly sure here not to pass an invalid
        // value (and cause a fatal error).
        $index = $index ? $index : NULL;
        $server
          ->deleteItems($ids, $index);
        break;
      default:

        // This should never happen.
        continue 2;
    }
    $executed_tasks[] = $task->id;
  }

  // If there were no tasks (we recognized), return TRUE.
  if (!$executed_tasks) {
    return TRUE;
  }

  // Otherwise, delete the executed tasks and check if new tasks were created
  // (or if we didn't even fetch all due to the 100 tasks limit).
  search_api_server_tasks_delete($executed_tasks);
  return $count_query
    ->execute()
    ->fetchField() === 0;
}