function drush_hosting_queued

7.x-3.x hosting_queued.drush.inc drush_hosting_queued()

Drush command to execute hosting tasks.

File

queued/hosting_queued.drush.inc, line 34
Dispatcher daemon

Code

function drush_hosting_queued() {
  if (function_exists('pcntl_signal')) {
    // reload the server on SIGHUP
    pcntl_signal(SIGHUP, 'hosting_queued_restart');
    pcntl_signal(SIGINT, 'hosting_queued_stop');
    pcntl_signal(SIGTERM, 'hosting_queued_stop');
  }

  // Set a nice high time limit, if we can:
  if (function_exists('set_time_limit')) {
    @set_time_limit(0);
  }

  // in some environments (e.g. in "productin") ENV is not actually
  // set (!) so try to guess from $_SERVER
  if (strpos(ini_get('variables_order'), 'E') === FALSE) {
    if (strpos(ini_get('variables_order'), 'S') === FALSE) {
      drush_log(dt('Neither $_ENV nor $_SERVER are available to set up proper environment inheritance; ensure E and/or S is set in your php.ini\'s "variables_order" setting.'), 'warning');
    }
    else {
      $_ENV = $_SERVER;
    }
  }

  $end_time = variable_get('hosting_queued_process_lifetime', 3600) + REQUEST_TIME;

  // Record the fact that we're running, so we can give some feedback in the
  // frontend.
  variable_set('hosting_queued_process_started', REQUEST_TIME);

  watchdog('hosting_queued', 'Started Hosting queue daemon, waiting for new tasks');

  while (TRUE) {
    try {
      // Should we terminate.
      if (REQUEST_TIME > $end_time) {
        // Restart the daemon to recycle leaked memory
        hosting_queued_restart();
      }
    }
    catch (Exception $e) {
      // Check if there was a database error, so we can recover gracefully if needed.
      // See: https://drupal.org/node/1992254.
      drush_log('Caught database error.', 'warning');
      $db = drush_convert_db_from_db_url($GLOBALS['db_url']);
      drush_log('Waiting for database to become available.', 'warning');
      do {
        // Give the database time to come back.
        sleep(1);
        // Check connection
        $connect = @mysqli_connect($db['host'], $db['username'], $db['password']);
        drush_log('.', 'warning');
      } while (!$connect);
      // Close connection
      mysqli_close($connect);
      drush_log('Restarting queue daemon.', 'warning');
      hosting_queued_restart();
    }

    // Get some tasks to run
    if ($tasks = @_hosting_get_new_tasks()) {
      if (lock_acquire('hosting_queue_tasks_running', HOSTING_QUEUE_LOCK_TIMEOUT)) {
        drush_log('Acquired lock on task queue.');
        foreach ($tasks as $task) {
          // We sleep for a second just in case others want to run the task first.
          // This guards against other processes that want to add a hosting task
          // with arguments and run it immediately, they should be able to do this
          // without us getting in there first.
          // This is a workaround for http://drupal.org/node/1003536
          drush_log(dt('Found task to execute. Pausing before execution.'));
          sleep(1);

          watchdog('hosting_queued', 'Running task @nid.', array('@nid' => $task->nid));
          // Execute the task in the backend
          drush_invoke_process('@self', 'hosting-task', array($task->nid), array('strict' => FALSE), array('interactive' => TRUE));
          drush_log(dt('Finished executing task.'));

          // Delay for a configurable amount of time.
          $delay = variable_get('hosting_queued_post_task_delay', 0);
          if (!empty($delay)) {
            drush_log(dt('Going to sleep for @count seconds after completing task.', array('@count' => $delay)));
            sleep($delay);
          }

          // We're done with this task, this unset might help reduce memory usage.
          unset($task);

          // Should we terminate.
          if (REQUEST_TIME > $end_time) {
            // Restart the daemon to recycle leaked memory
            hosting_queued_restart();
          }
        }
        drush_log('Releasing lock on task queue.');
        lock_release('hosting_queue_tasks_running');
      }
    }

    // wait here only if we didn't process tasks
    // this is to avoid an infinite loop if there are no tasks in the queue
    if (!$tasks) {
      sleep(1);
    }

    if (drush_get_option('onetime')) {
      drush_log(dt("exiting after processing all tasks, as requested by --onetime"));
      break;
    }
    unset($tasks);
  }
}