Precondition Functions
Preconditions are used to determine if a step or chain process is to be started or skipped.
The precondition is a boolean function (it returns "true" or "false") which is written in Redwood Expression Language or defined by a time window (when time window is open, the precondition returns true otherwise false ).
Preconditions on step are executed immediately before the set[ is supposed to start; preconditions on chain processes are executed when the step starts.
When the precondition function returns:
- "true" (default when none has been defined) processing continues.
- "false", the step or chain process is skipped.
note
REL Expressions always start with an equals sign (=).
Preconditions are executed each time its chain process or step is executed, so even when you restart a chain process or step, the function will be executed. You can influence the restart behavior of steps and chain processes in a number of ways. A special Repository.shouldRunAgain()
precondition function has been introduced to cater for restart functionality. This function returns true as long as the chain process has not reached status Completed and is used for restarts.
=Repository.shouldRunAgain()
- valid only on a call, returns true if the call has not reached Completed before. Note that this can create loops, especially if you use it in combination with automatic restarts.
See Redwood Expression Language for a list of built-in REL functions.
You can also create your own in Libraries using RedwoodScript and REL Entry Points; remember you need to create boolean functions. An example of a RedwoodScript function is provided below.
Chain Final Status
The final status of a chain is determined by the status of the last step that reached a final state; the following final states are mapped to Completed
: Disabled
, Skipped
, Ignored
.
You can use keywords and a registry entry to toggle this behavior.
The following comments can be used to enable the new behavior:
@useLastExecutedStepStatus=true
To disable, use the following:
@useLastExecutedStepStatus=false
Just place the keyword (including @ and the desired value, true or false) into the Documentation field on the Documentation tab of a chain.
Registry Settings
The registry entry that governs the default behavior:
/configuration/jcs/jobchain/useLastExecutedStepStatus
The registry entry can be set to true
or false
(default).
true
means that if you have a chain of which the last step is Disabled
, for example, the final status of the chain will be that of the preceding step, if this step is not in one of the previously mentioned states.
Chains and Restart Behavior
The Restart Behavior is only evaluated at the end of the step. When a step is skipped, due to a precondition, for example, the restart behavior is not evaluated, since the step does not run, thus does not finish. Therefore you have to put the precondition on the chain process, so it goes to Skipped and not the step. This can be an issue if you use stepIterations < n
preconditions, where n
is a number.
note
Preconditions may be executed before the chain process is persisted, or, saved to the database. This can occur in chains when the step reaches status Console and is restarted; it has the effect that it is not possible to access itself or any other chain process.
The following substitution parameters are specifically tailored for use in preconditions in chains that have calls that are supposed to restart. Since upon restart, the preconditions are evaluated before the chain process is persisted, you cannot access properties directly.
stepJobId
,stepUniqueId
- step and call preconditionscallJobId
,callUniqueId
- call preconditions
Procedure
- Choose "Definitions > Chains".
- From the context-menu, choose Edit.
- Select a step or chain process and choose Edit Step or Edit Chain Process.
- Choose Precondition and fill in an expression.
- Choose Save and Close.
Example
Using REL Time Window Function
In this example, a test is done to see if the time window System_Week_WorkDays is open at this time. The function Time.now() returns the current system date time in the specified time zone. The function Time.isTimeWindowOpen( time
, time_window
) tests if the time window time_window
is open at a given time time
. Note that time window-based preconditions are built-in, that is, you may specify simply the time window, the current time zone will be used to evaluate the time window. Using the REL expression below, you can specify another time zone or even dynamic time (three hours before now, for example).
In the below example the following is true:
- Time window
System_Week_WorkDays
is open on workdays only - The time now
Time.now('GMT')
is 2023/09/28 10:50:44,910 GMT
If the following expression is false the chain process is skipped:
=Time.isTimeWindowOpen(Time.now('GMT'), 'System_Week_WorkDays')
Using Your Function
In this example a developer at Example has created two trivial functions in RedwoodScript; one that returns true and the other false. This example illustrates how you can create your logic seamlessly.
In the built-in Custom library, the following has been added to the source:
// Example code to illustrate
package example;
public class func
{
public static boolean alwaysTrue()
{
return true;
}
public static boolean alwaysFalse()
{
return false;
}
}
The following two REL Entry Points have also been added so the code can be called from REL in parameters or precondition functions, for example:
Name | FQ Class Name | Method Signature |
---|---|---|
alwaysTrue | example.func | alwaysTrue() |
alwaysFalse | example.func | alwaysFalse() |
You specify the function in the precondition function field as follows:
=<library_name>.<method_name>([<arg1>, <arg2> ..., <argN>])
In this case for alwaysTrue():
=Cuctom.alwaysTrue()
or for alwaysFalse():
Custom.alwaysFalse()
note
Redwood recommends you create your REL Entry Points in a precondition-specific library to avoid unnecessary recompiling. All RedwoodScript scripting contexts (process definitions, triggers, etc) that use a library are recompiled when the library is modified; note that your library names must always have a Custom_ prefix.
Create a Chains in RedwoodScript with a Precondition
The developer created a chain with RedwoodScript and set a precondition she created previously on the chain process:
{
String pPartition = "RW_DEMO";
String jdName = "MyJobChainWithPrecondition";
String stepName = "Stepartition 1";
String pfunction = "=Custom.alwaysFalse()";
//get or create a partition (here we create one if it does not already exist)
Partition partition = jcsSession.getPartitionByName(pPartition);
if (partition == null)
{
partition = jcsSession.createPartition();
partition.setName(pPartition);
}
JobDefinition jDefinition = jcsSession.getJobDefinitionByName(partition, jdName);
if (jDefinition == null)
{
//Create JobDefinition of type JOB_CHAIN (chain definition)
jDefinition = jcsSession.createJobDefinition();
jDefinition.setName(jdName);
jDefinition.setJobDefinitionType(jcsSession.getJobDefinitionTypeByName(JobDefinitionType.JOB_CHAIN));
jDefinition.setPartition(partition);
//Create jobchain object with one step and one job chain call
JobChain jchain = jcsSession.createJobChain();
jchain.setJobDefinition(jDefinition);
//step
JobChainStepartition jcstep = jchain.createJobChainStep();
jcstep.setSequenceNumber(Long.valueOf(0));
jcstep.setName(stepName);
//job chain call
JobChainCall jccall = jcstep.createJobChainCall();
JobDefinition ssleep = jcsSession.getJobDefinitionByName("System_Sleep");
jccall.setJobDefinition(ssleep);
jccall.setSequenceNumber(Long.valueOf(0));
jccall.createJobChainCallPrecondition().setExpression(pfunction);
}
else
{
jcsOut.println("JobDefinition " + jdName + " exists!");
jcsOut.println("You can change the JobDefinition name on the line:\n String jdName = \"MyJobChainWithPrecondition\";");
}
jcsSession.persist();
}