KBEC-00139 - Preventing simultaneous executions of a job

Article ID:360033193871
2 minute readKnowledge base

Summary

You may have a job that you only want to run one at a time. For example, it may be a job that is set to run once an hour from a schedule, but sometimes you want to run it manually. If you started it manually and it is still running when the schedule triggers, you want the manual one to keep running, but you do not want the scheduled one to run. Or, the situation may be reversed, you may start it manually when it is already running from the schedule.

Solution

To address this, add a step to the beginning of your Procedure that will scan for existing jobs that are running of the same "type". In the example below, the "type" is based on the Project name and Procedure name, but you can customize the step to include additional criteria, such as a special property.

This example also does some extra cleanup. It finds and removes old jobs that were terminated by this mechanism so that they do not clutter your reports, and so on. It also cleans up their workspaces.

Step to Add to Your Procedure

Create a step like this at the beginning of your main procedure in your environment:

Name: Check For Running Jobs
Shell: ec-perl
Error Handling: Abort entire job and terminate running steps
Command:

use strict;
use ElectricCommander ();
my $ec = new ElectricCommander();

# Set up Filter for running jobs with the same Project/Procedure
my @filterList;
push (@filterList, {
    "propertyName" => "projectName",
    "operator" => "equals",
    "operand1" => "$[/myJob/projectName]"});
push (@filterList, {
    "propertyName" => "procedureName",
    "operator" => "equals",
    "operand1" => "$[/myJob/procedureName]"});
push (@filterList, {
    "propertyName" => "status",
    "operator" => "notEqual",
    "operand1" => "completed"});

# Find the jobs
my $xPath = $ec->findObjects("job", {filter => \@filterList });

# Check on the number of matching jobs
# just one - That's me!
# more than one - We are not alone
my @nodes = $xPath->findnodes('//job');
if ( scalar(@nodes) != 1) {
    $ec->setProperty("summary", "An existing job of this type is already running",  {jobStepId => $[jobStepId]});
    exit 1;
}

The exit 1 will cause the job to fail and skip the rest of the steps if there is another job running with the same Project/Procedure. This would be a good candidate to put into a shared library and call it as a function.