Tripal v1.0 (6.x-1.0)
|
Functions | |
tripal_add_job ($job_name, $modulename, $callback, $arguments, $uid, $priority=10) | |
tripal_jobs_check_running () | |
tripal_jobs_get_start_time ($job) | |
tripal_jobs_get_end_time ($job) | |
tripal_jobs_rerun ($job_id, $goto_jobs_page=TRUE) | |
tripal_jobs_cancel ($job_id, $redirect=TRUE) | |
tripal_jobs_launch ($do_parallel=0, $job_id=NULL) | |
tripal_get_module_active_jobs ($modulename) | |
tripal_jobs_get_submit_date ($job) |
Tripal offers a job management subsystem for managing tasks that may require an extended period of time for completion. Drupal uses a UNIX-based cron job to handle tasks such as checking the availability of updates, indexing new nodes for searching, etc. Drupal's cron uses the web interface for launching these tasks, however, Tripal provides several administrative tasks that may time out and not complete due to limitations of the web server. Examples including syncing of a large number of features between chado and Drupal. To circumvent this, as well as provide more fine-grained control and monitoring, Tripal uses a jobs management sub-system built into the Tripal Core module. It is anticipated that this functionality will be used for managing analysis jobs provided by future tools, with eventual support for distributed computing.
The Tripal jobs management system allows administrators to submit tasks to be performed which can then be launched through a UNIX command-line PHP script or cron job. This command-line script can be added to a cron entry along-side the Drupal cron entry for automatic, regular launching of Tripal jobs. The order of execution of waiting jobs is determined first by priority and second by the order the jobs were entered.
The API functions described below provide a programmatic interface for adding, checking and viewing jobs.
tripal_add_job | ( | $ | job_name, |
$ | modulename, | ||
$ | callback, | ||
$ | arguments, | ||
$ | uid, | ||
$ | priority = 10 |
||
) |
Adds a job to the Tripal Jbo queue
$job_name | The human readable name for the job |
$modulename | The name of the module adding the job |
$callback | The name of a function to be called when the job is executed |
$arguments | An array of arguements to be passed on to the callback |
$uid | The uid of the user adding the job |
$priority | The priority at which to run the job where the highest priority is 10 and the lowest priority is 1. The default priority is 10. |
Example usage:
$args = array($dfile, $organism_id, $type, $library_id, $re_name, $re_uname, $re_accession, $db_id, $rel_type, $re_subject, $parent_type, $method, $user->uid, $analysis_id, $match_type); tripal_add_job("Import FASTA file: $dfile", 'tripal_feature', 'tripal_feature_load_fasta', $args, $user->uid);
The code above is copied from the tripal_feature/fasta_loader.php file. The snipped first builds an array of arguments that will then be passed to the tripal_add_job function. The number of arguments provided in the $arguments variable should match the argument set for the callback function provided as the third argument.
Definition at line 64 of file tripal_core_jobs.api.inc.
{ // convert the arguments into a string for storage in the database $args = implode("::", $arguments); $record = new stdClass(); $record->job_name = $job_name; $record->modulename = $modulename; $record->callback = $callback; $record->status = 'Waiting'; $record->submit_date = time(); $record->uid = $uid; $record->priority = $priority; # the lower the number the higher the priority if ($args) { $record->arguments = $args; } if (drupal_write_record('tripal_jobs', $record)) { $jobs_url = url("admin/tripal/tripal_jobs"); drupal_set_message(t("Job '%job_name' submitted. Check the <a href='!jobs_url'>jobs page</a> for status", array('%job_name' => $job_name, '!jobs_url' => $jobs_url))); } else { drupal_set_message(t("Failed to add job %job_name.", array('%job_name' => $job_name)), 'error'); } return $record->job_id; }
tripal_get_module_active_jobs | ( | $ | modulename | ) |
Returns a list of jobs associated with the given module
$modulename | The module to return a list of jobs for |
Definition at line 339 of file tripal_core_jobs.api.inc.
{ $sql = "SELECT * FROM {tripal_jobs} TJ ". "WHERE TJ.end_time IS NULL and TJ.modulename = '%s' "; return db_fetch_object(db_query($sql, $modulename)); }
tripal_jobs_cancel | ( | $ | job_id, |
$ | redirect = TRUE |
||
) |
Cancel a Tripal Job currently waiting in the job queue
$job_id | The job_id of the job to be cancelled |
Definition at line 214 of file tripal_core_jobs.api.inc.
{ $sql = "SELECT * FROM {tripal_jobs} WHERE job_id = %d"; $job = db_fetch_object(db_query($sql, $job_id)); // set the end time for this job if ($job->start_time == 0) { $record = new stdClass(); $record->job_id = $job->job_id; $record->end_time = time(); $record->status = 'Cancelled'; $record->progress = '0'; drupal_write_record('tripal_jobs', $record, 'job_id'); drupal_set_message(t("Job #%job_id cancelled", array('%job_id' => $job_id))); } else { drupal_set_message(t("Job %job_id cannot be cancelled. It is in progress or has finished.", array('%job_id' => $job_id))); } if ($redirect) { drupal_goto("admin/tripal/tripal_jobs"); } }
tripal_jobs_check_running | ( | ) |
Returns a list of running tripal jobs
Definition at line 98 of file tripal_core_jobs.api.inc.
{ // iterate through each job that has not ended // and see if it is still running. If it is not // running but does not have an end_time then // set the end time and set the status to 'Error' $sql = "SELECT * FROM {tripal_jobs} TJ ". "WHERE TJ.end_time IS NULL and NOT TJ.start_time IS NULL "; $jobs = db_query($sql); while ($job = db_fetch_object($jobs)) { $status = `ps --pid=$job->pid --no-header`; if ($job->pid && $status) { // the job is still running so let it go // we return 1 to indicate that a job is running return TRUE; } else { // the job is not running so terminate it $record = new stdClass(); $record->job_id = $job->job_id; $record->end_time = time(); $record->status = 'Error'; $record->error_msg = 'Job has terminated unexpectedly.'; drupal_write_record('tripal_jobs', $record, 'job_id'); } } // return 1 to indicate that no jobs are currently running. return FALSE; }
tripal_jobs_get_end_time | ( | $ | job | ) |
Returns the end time for a given job
$job | An object describing the job |
Definition at line 167 of file tripal_core_jobs.api.inc.
tripal_jobs_get_start_time | ( | $ | job | ) |
Returns the start time for a given job
$job | An object describing the job |
Definition at line 140 of file tripal_core_jobs.api.inc.
tripal_jobs_get_submit_date | ( | $ | job | ) |
Returns the date the job was added to the queue
$job | An object describing the job |
Definition at line 356 of file tripal_core_jobs.api.inc.
{ return format_date($job->submit_date); }
tripal_jobs_launch | ( | $ | do_parallel = 0 , |
$ | job_id = NULL |
||
) |
A function used to manually launch all queued tripal jobs
$do_parallel | A boolean indicating whether jobs should be attempted to run in parallel |
$job_id | To launch a specific job provide the job id. This option should be used sparingly as the jobs queue managment system should launch jobs based on order and priority. However there are times when a specific job needs to be launched and this argument will allow it. Only jobs which have not been run previously will run. |
Definition at line 251 of file tripal_core_jobs.api.inc.
{ // 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_jobs_check_running()) { print "Jobs are still running. Use the --parallel=1 option with the Drush command to run jobs in parallel."; return; } // get all jobs that have not started and order them such that // they are processed in a FIFO manner. if ($job_id) { $sql = "SELECT * FROM {tripal_jobs} TJ ". "WHERE TJ.start_time IS NULL and TJ.end_time IS NULL and TJ.job_id = %d ". "ORDER BY priority ASC,job_id ASC"; $job_res = db_query($sql,$job_id); } else { $sql = "SELECT * FROM {tripal_jobs} TJ ". "WHERE TJ.start_time IS NULL and TJ.end_time IS NULL ". "ORDER BY priority ASC,job_id ASC"; $job_res = db_query($sql); } while ($job = db_fetch_object($job_res)) { // set the start time for this job $record = new stdClass(); $record->job_id = $job->job_id; $record->start_time = time(); $record->status = 'Running'; $record->pid = getmypid(); drupal_write_record('tripal_jobs', $record, 'job_id'); // call the function provided in the callback column. // Add the job_id as the last item in the list of arguments. All // callback functions should support this argument. $callback = $job->callback; $args = split("::", $job->arguments); $args[] = $job->job_id; print "Calling: $callback(" . implode(", ", $args) . ")\n"; call_user_func_array($callback, $args); // set the end time for this job $record->end_time = time(); $record->status = 'Completed'; $record->progress = '100'; drupal_write_record('tripal_jobs', $record, 'job_id'); // send an email to the user advising that the job has finished } }
tripal_jobs_rerun | ( | $ | job_id, |
$ | goto_jobs_page = TRUE |
||
) |
Set a job to be re-ran (ie: add it back into the job queue)
$job_id | The job_id of the job to be re-ran |
Definition at line 186 of file tripal_core_jobs.api.inc.
{ global $user; $sql = "SELECT * FROM {tripal_jobs} WHERE job_id = %d"; $job = db_fetch_object(db_query($sql, $job_id)); $args = explode("::", $job->arguments); $job_id = tripal_add_job( $job->job_name, $job->modulename, $job->callback, $args, $user->uid, $job->priority); if ($goto_jobs_page) { drupal_goto("admin/tripal/tripal_jobs"); } return $job_id; }