Browse Source

Merge branch '7.x-3.x' of github.com:tripal/tripal into 7.x-3.x

Stephen Ficklin 7 years ago
parent
commit
61b7f736a5

+ 1 - 0
tripal/tripal.module

@@ -692,6 +692,7 @@ function tripal_block_info() {
  */
 function tripal_block_view($delta = ''){
   global $base_path;
+  $block = array();
 
   // The $delta parameter tells us which block is being requested.
   switch ($delta) {

+ 79 - 65
tripal_daemon/TripalDaemon.inc

@@ -23,6 +23,11 @@ class TripalDaemon extends DrushDaemon {
   // inherits from a library class.
   protected $loop_interval = 20;
 
+  // Keep track of whether we are running a Tripal job or not
+  // and if so, which Tripal jobs are we running.
+  // If this array is empty then we are waiting for jobs ;-).
+  protected $tripal_jobs = array();
+
   /**
    * Implements DaemonAPIDaemon::executeTask() function.
    *
@@ -38,78 +43,87 @@ class TripalDaemon extends DrushDaemon {
    *   This is an integer stating the current iteration of the loop you are on.
    */
   protected function executeTask($iteration_number) {
+ 
+    $do_parallel = FALSE;
+    $max_jobs = 1;
 
-    // When sorting the job list we want to use version specific SQL and thus
-    // need to know the postgreSQL version to determine what SQL to execute.
-    $version_string = db_query('SELECT version()')->fetchField();
-    if (preg_match('/PostgreSQL (\d+)\.(\d+)/', $version_string, $matches)) {
-      $version = array('major' => $matches[1], 'minor' => $matches[2]);
+    // First check if any jobs are currently running if they are, don't continue,
+    // we don't want to have more than one job script running at a time.
+    if (!$do_parallel and tripal_is_job_running()) {
+      $this->log("Jobs are still running. Use the --parallel=1 option with the Drush command to run jobs in parallel.\n");
     }
-    // If we can't determine the version then use the deprecated method.
-    else {
-      $version = array('major' => 8, 'minor' => 4);
-    }
-
-    // First check to see if there are any tripal jobs to be run.
-    if ($version['major'] >= 9 ) {
-      $waiting_jobs = db_query(
-        "SELECT
-          count(*) as count,
-          array_to_string(array_agg(j.job_id ORDER BY j.priority ASC, j.job_id ASC),'|') as jobs
-        FROM {tripal_jobs} j
-        WHERE j.status = 'Waiting'"
-      )->fetchObject();
+    elseif ($do_parallel && tripal_max_jobs_exceeded($max_jobs)) {
+      $this->log("At least $max_jobs jobs are still running. At least one of these jobs much complete before a new job can start.\n");
     }
     else {
-     $waiting_jobs = db_query(
-        "SELECT
-          count(*) as count,
-          array_to_string(array_agg(j.job_id),'|') as jobs
-        FROM (SELECT * FROM {tripal_jobs} WHERE j.status = 'Waiting' ORDER BY priority ASC, job_id ASC) as j"
-      )->fetchObject();
-    }
 
-    $num_waiting_jobs = $waiting_jobs->count;
-    $job_ids = explode('|', $waiting_jobs->jobs);
-
-    // If there are then run them and log the output.
-    if ($num_waiting_jobs > 0) {
-      $this->log($num_waiting_jobs . ' Waiting Tripal Jobs... '
-        . 'Running waiting job(s) now.');
-
-      // Launch all tripal jobs :) Yay for bootstrapping!!
-      foreach ($job_ids as $id) {
-        $this->log('Starting Job (ID=' . $id . ')', '', 1);
-
-        // We would like to log the output from the job.
-        // However, most tripal jobs simply print to the screen :-(
-        // Thus we have to use output buffering to capture the output.
-        // Start Buffering.
-        ob_start();
-
-        // Launch Tripal Job.
-        tripal_launch_job(FALSE, $id);
-
-        // Save the buffer to the log and stop buffering.
-        $this->log(str_repeat('=', 80));
-        $this->log(ob_get_clean());
-        $this->log(str_repeat('=', 80));
-
-        // Report job details.
-        $job = db_query(
-          "SELECT j.*
-          FROM {tripal_jobs} j
-          WHERE j.job_id = :jid",
-          array(':jid' => $id)
-        )->fetchObject();
-        $this->log("Job completed at "
-        . date('d M Y H:i:s', $job->end_time) . " with a status of '"
-        . $job->status . "'", "", 1);
+      // First check to see if there are any tripal jobs to be run.
+      $sql =  "
+        SELECT TJ.job_id
+        FROM {tripal_jobs} TJ
+        WHERE
+          TJ.start_time IS NULL AND
+          TJ.end_time IS NULL AND
+          NOT TJ.status = 'Cancelled'
+        ORDER BY priority ASC,job_id ASC";
+      $job_ids = db_query($sql)->fetchCol();
+      $num_waiting_jobs = sizeof($job_ids);
+
+      // If there are then run them and log the output.
+      if ($num_waiting_jobs > 0) {
+        $this->log($num_waiting_jobs . ' Waiting Tripal Jobs... '
+          . 'Running waiting job(s) now.');
+
+        // Launch all tripal jobs :) Yay for bootstrapping!!
+        foreach ($job_ids as $id) {
+          $this->log('Starting Job (ID=' . $id . ')', '', 1);
+
+          // Tell admins we are running a job.
+          $this->tripal_jobs[$id] = $id;
+          $this->setStatus();
+
+          // Launch Tripal Job.
+          $job = new TripalJob();
+          $job->load($id);
+          try {
+            $job->run();
+          }
+          catch (Exception $e) {
+            $job->logMessage($e->getMessage(), array(), TRIPAL_ERROR);
+          } 
+
+          // Tell admins that we're done :-).
+          unset($this->tripal_jobs[$id]);
+          $this->setStatus();
+
+          // Report job details.
+          $job = db_query(
+            "SELECT j.*
+            FROM {tripal_jobs} j
+            WHERE j.job_id = :jid",
+            array(':jid' => $id)
+          )->fetchObject();
+          $this->log("Job (ID=" . $id . ") completed at "
+          . date('d M Y H:i:s', $job->end_time) . " with a status of '"
+          . $job->status . "'", "", 1);
+        }
       }
     }
-    else {
-      $this->log('There are no Tripal Jobs to run');
-    }
+  }
+
+  /**
+   * Override to include additional daemon-specific settings for use in reports.
+   *
+   * @return array
+   *   An array of status details where the key should be a human-readable
+   *   name for your detail and the value should be the current state.
+   */
+  protected function getStatusDetails() {
+    $status_details = parent::getStatusDetails();
+
+    $status_details['Running Job'] = (empty($this->tripal_jobs)) ? FALSE : TRUE;
+    $status_details['Current Jobs'] = $this->tripal_jobs;
 
+    return $status_details;
   }
 }

+ 137 - 15
tripal_daemon/includes/tripal_daemon.blocks.inc

@@ -10,8 +10,23 @@
 function tripal_daemon_block_info() {
   $blocks = array();
 
-  $blocks['tripal_daemon_status'] = array(
+  // Status Blocks.
+  $blocks['trpdaemon_status'] = array(
     'info' => t('Tripal Daemon Status'),
+    'cache' => DRUPAL_NO_CACHE,
+  );
+  $blocks['trpdaemon_status_admin'] = array(
+    'info' => t('Tripal Daemon Status: ADMIN'),
+    'cache' => DRUPAL_NO_CACHE,
+    'status' => TRUE,
+    'region' => 'dashboard_sidebar',
+  );
+
+  // Display Log Block.
+  $blocks['trpdaemon_log'] = array(
+    'info' => t('Tripal Daemon Log'),
+    'status' => TRUE,
+    'region' => 'dashboard_main',
   );
   
   return $blocks;
@@ -24,59 +39,166 @@ function tripal_daemon_block_view($delta='') {
   $block = array();
 
   switch($delta) {
-    case 'tripal_daemon_status':
-      $is_running = drushd_is_daemon_running('tripal_daemon');
-      $status_class = ($is_running) ? 'active' : 'inactive';
+    case 'trpdaemon_status_admin':
+      $block['subject'] = t('Job Daemon Status');
+      $block['content'] = theme_tripal_daemon_status_block_content(TRUE);
+      break;
+    case 'trpdaemon_status':
       $block['subject'] = t('Job Daemon Status');
       $block['content'] = theme_tripal_daemon_status_block_content();
       break;
+    case 'trpdaemon_log':
+      $block['subject'] = t('Job Daemon Log');
+      $block['content'] = drupal_get_form('trpdaemon_display_log_form');
+      break;
   }
   
   return $block;
 }
 
 /** 
+ * Provide markup for the Tripal Job Daemon Status block.
  *
+ * @param $show_all
+ *   A boolean indicating whether to show administrative detail (TRUE) or not (FALSE).
+ * @return
+ *   HTML to be rendered for the block.
  */
-function theme_tripal_daemon_status_block_content() {
+function theme_tripal_daemon_status_block_content($show_all = FALSE) {
   $output = '';
 
   // Get information.
   $is_running = drushd_is_daemon_running('tripal_daemon');
   $status_file = drushd_get_daemon_status_file('tripal_daemon');
   $status = unserialize(file_get_contents($status_file));
+  $PID = $status['PID'];
+  $is_alive = `ps h --pid $PID | wc -l`;
+  $is_alive = trim($is_alive);
 
   $status_class = ($is_running) ? 'active' : 'inactive';
+  $status_class = ($is_running AND !$is_alive) ? 'dead' : $status_class;
 
   // Theme content.
   drupal_add_css(drupal_get_path('module','tripal_daemon') . '/theme/status_block.css');
 
+  // Display the status.
   $output .= '<div class="daemon-status">';
-  if ($is_running) {
+  if ($is_running and $is_alive) {
     $output .= theme_image(array(
       'path' => 'misc/message-24-ok.png',
       'alt' => 'status-ok',
     ));
-    $output .= 'Running';
+    if ($status['Running Job']) {
+      $output .= 'Running Job(s)';
+    }
+    else {
+      $output .= 'Waiting for Job';
+    }
   }
   else {
     $output .= theme_image(array(
       'path' => 'misc/message-24-error.png',
       'alt' => 'status-error',
     ));
-    $output .= 'Stopped';
+    if ($is_running AND !$is_alive) {
+      $output .= 'Dead';
+    }
+    else {
+      $output .= 'Stopped';
+    }
   }
   $output .= '</div>';
 
-  $output .= '<ul>';
-  foreach ($status as $k => $v) {
-    if (is_bool($v)) {
-      $v = ($v) ? 'True' : 'False';
-    }
+  // If asked, show all the details.
+  if ($show_all) {
+    $output .= '<ul>';
+    foreach ($status as $k => $v) {
+
+      // If it's a boolean, then make it readable.
+      if (is_bool($v)) {
+        $v = ($v) ? 'True' : 'False';
+      }
+
+      // If these are current jobs then we want to link to details.
+      if ($k == 'Current Jobs' AND !empty($v)) {
+        foreach ($v as $job_id) {
+          $url = 'admin/tripal/tripal_jobs/view/' . $job_id;
+          $v[$job_id] = l($job_id, $url);
+        }
+      }
 
-    $output .= '<li><strong>' . $k . '</strong>: ' . $v . '</li>';
+      // If it's an array then make it a list.
+      if (is_array($v)) {
+        if (empty($v)) {
+          $v = 'None';
+        }
+        else {
+          $v = implode(', ', $v);
+        }
+      }
+
+      $output .= '<li><strong>' . $k . '</strong>: ' . $v . '</li>';
+    }
+    $output .= '</ul>';
   }
-  $output .= '</ul>';
 
   return '<div class="inner '.$status_class.'">' . $output . '</div>';
 }
+
+/**
+ * Form to display a user selected number of lines from the Tripal Job Daemon log file.
+ */
+function trpdaemon_display_log_form($form, $form_state) {
+
+  $form['#attached']['css'][] = drupal_get_path('module','tripal_daemon') . '/theme/tripal_daemon.log_block.css';
+
+  $status_file = drushd_get_daemon_status_file('tripal_daemon');
+  $status = unserialize(file_get_contents($status_file));
+  $file = $status['Current Log File'];
+
+  $form['num_lines'] = array(
+    '#type' => 'radios',
+    '#title' => 'Lines',
+    '#description' => 'The number of lines to display from the end of the Tripal Job Daemon Log file.',
+    '#options' => array(
+      '10' => '10',
+      '25' => '25',
+      '50' => '50',
+      '100' => '100',
+      '200' => '200',
+      '500' => '500',
+    ),
+    '#default_value' => '25',
+    '#attributes'     => array(
+      'onChange' => 'this.form.submit();',
+      'class' => array('container-inline'),
+    ),
+  );
+  $num_lines = (isset($form_state['values'])) ? $form_state['values']['num_lines'] : $form['num_lines']['#default_value'];
+
+  $text = `tail -n $num_lines $file`;
+  $text = str_replace("\n", '<br />', $text);
+  $form['log'] = array(
+    '#type' => 'markup',
+    '#markup' => $text,
+    '#prefix' => '<pre id="daemon-log">',
+    '#suffix' => '</pre>',
+  );
+
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Apply'),
+    '#attributes' => array(
+      'style' => array('display: none;'),
+     ),
+  );
+
+  return $form;
+}
+
+/**
+ * Display Log Form: Submit.
+ */
+function trpdaemon_display_log_form_submit($form, &$form_state) {
+  $form_state['rebuild'] = TRUE;
+}

+ 13 - 7
tripal_daemon/theme/status_block.css

@@ -1,29 +1,35 @@
 /**
  * Tripal Daemon Status Block.
  */
-#dashboard #block-tripal-daemon-tripal-daemon-status div.content,
-  div#block-tripal-daemon-tripal-daemon-status div.content {
+#dashboard div.block.block-tripal-daemon div.content,
+  div.block-tripal-daemon div.content {
     padding: 0;
 }
-#block-tripal-daemon-tripal-daemon-status div.content div.inner {
+div.block-tripal-daemon div.content div.inner {
   padding: 15px; 
 }
-#block-tripal-daemon-tripal-daemon-status .active {
+
+div.block-tripal-daemon .active {
   background-color: #f8fff0; 
   color: #234600;
 }
-#block-tripal-daemon-tripal-daemon-status .inactive {
+div.block-tripal-daemon .dead {
   background-color: #fef5f1;
   color: #8c2e0b;
 }
+div.block-tripal-daemon .inactive {
+  background-color: #fef5f1;
+  color: #b3b3b3;
+}
 
-#block-tripal-daemon-tripal-daemon-status .daemon-status {
+div.block-tripal-daemon .daemon-status {
   font-weight: bolder;
   font-size: 1.2em;
   margin-bottom: 15px;
 }
-#block-tripal-daemon-tripal-daemon-status .daemon-status img {
+div.block-tripal-daemon .daemon-status img {
   top: 6px;
   position: relative;
   padding-right: 5px;
+  border: 0;
 }

+ 12 - 0
tripal_daemon/theme/tripal_daemon.log_block.css

@@ -0,0 +1,12 @@
+/**
+ * Themeing for the Tripal Daemon Log Block.
+ */
+
+#trpdaemon-display-log-form {
+  padding: 15px;
+}
+
+#trpdaemon-display-log-form .form-radios .form-item {
+  padding-right: 5px;
+}
+