Scope

The Join Orders Job (JobSchedulerJoinOrders) is a JITL Job and is used to join up parallel executing child segments in a Job Chain. It then continues processing with a single Order in a single thread once processing of the parallel threads has been completed. It is used in two Job Chain Patterns - Split and Join and "Y".

This article describes how the Join Orders Job can be used in a "Y" pattern - the How to Execute Jobs in a Job Chain in Parallel article describes its use in a Split and Join pattern.

The Join Orders Job is only available for JobScheduler versions 1.11.4 and newer.

Join Patterns

The example described in this article shows the use of a single instance of the Join Orders Job within a single Job Chain. Multiple instances of the Join Orders Job can also be used within a Job Chain. See the Configuration section of the JobSchedulerJoinOrders documentation for more information.  

split and join Pattern

The configuration of the Join Orders Job for use in the Split and Join pattern is described in the How to Execute Jobs in a Job Chain in Parallel article.

Relevant for the current article is that in the Split and Join pattern, the Split Job generates the configuration information required by the Join Orders job. This information must be configured separately for the "Y" pattern. The information generated by the the Split Job is:

'Y' Pattern

The following diagram shows the "Y"-pattern Job Chain used in the example download archive that is linked from this article.

main [label="Order:main_order",fillcolor="green"]
100 [label="generate orders",fillcolor="lightskyblue"]
add [label="Order:main_order_add-order",fillcolor="green"]
150 [label="wait",fillcolor="lightskyblue"]
200 [label="200 job_a",fillcolor="lightskyblue"]
300 [label="300 job_b",fillcolor="lightskyblue"]
join [label="join orders",fillcolor="lightskyblue"]
400 [label="400 job_c",fillcolor="lightskyblue"]
success [label="success",fillcolor="orange"]

main -> 100 
100 -> 150 
150  -> 200 
200 -> join 
add -> 300 
300 -> join 
join -> 400 
400 -> success 

Download and Configure the Example

Example Description

To use the example, first start the Parent Order (in this example main_order). This Order has been configured with three parameters, one of which - required_orders - is required by the Join Orders Job. The other two parameters - generate_orders and duration_wait_job are only used to provide a convenient way of making the example work.

The main_order_add-order Order can now be used to increase the the total number of Orders counted by the Join Orders Job by 1.

Note that Child Orders such as the generated Orders or the manually started main_order_add-order Order in this example will only be recognized as such when they are started after the Parent Order has been started.

The Job Chain, Jobs and Orders

The Job Chain

The Job Chain is shown in the diagram near the top of this article and is listed in the code block below.

<?xml version="1.0" encoding="ISO-8859-1"?>

<job_chain  title="Y Join">
    <job_chain_node  state="100" job="generate_orders" next_state="150" error_state="error"/>
    <job_chain_node  state="150" job="wait" next_state="200" error_state="error"/>
    <job_chain_node  state="200" job="job_a" next_state="join" error_state="error"/>
    <job_chain_node  state="300" job="job_b" next_state="join" error_state="error" delay="10"/>
    <job_chain_node  state="join" job="join" next_state="400" error_state="error"/>
    <job_chain_node  state="400" job="job_c" next_state="success" error_state="error"/>
    <job_chain_node  state="success"/>
    <job_chain_node  state="error"/>
</job_chain>

The Jobs

The Join Orders Job

The Join Orders Job basically counts incoming Jobs. This makes it significantly faster than the Sync Job mentioned in the Scope section above, which checks the incoming Jobs for completeness.

The configuration of the Join Orders Job can set using the JITL Job Wizard in JOE and is shown in following code block. Relevant for users in the following listing is the show_join order list parameter which may be optionally set (default is false). Setting this Parameter to true causes a list of all the orders counted by the Join Orders Job to be written to the Parent Order log file.

<?xml version="1.0" encoding="ISO-8859-1"?>

<job  order="yes" stop_on_error="no" idle_timeout="60" title="Join Job">
    <params >
        <param  name="show_join_order_list" value="true"/>
    </params>
    <script  language="java" java_class_path="" java_class="com.sos.jitl.join.JobSchedulerJoinOrdersJSAdapterClass"/>
    <run_time />
</job>

Note that the Join Orders Job only counts Orders that have the state of the Join Orders Job as their end state (here join).

The generate_orders Job

The configuration of the generate_orders Job is shown in the next code block along with the script responsible for the generation of the Child Orders.

Note that this Job is only used to create the current example and is not required for the Join Orders Job itself. In a working scheduling environment, the orders for the parallel parts of the "Y" would come from other sources such as Schedules or File Order Sources.

Note also that the Job Chain path (set in line 14 of the script) must be modified to suit the actual path used.

<?xml version="1.0" encoding="ISO-8859-1"?>

<job  order="yes" stop_on_error="no">
    <script  language="java:javascript">
        <![CDATA[
function spooler_process(){

    // merge parameters from task and order
    var params = spooler_task.params;
    params.merge( spooler_task.order.params );
 
    // set variable
    var generate_orders = params.value( 'generate_orders' );
    var jobChain = spooler.job_chain('/test/join/y_join/y_join');

    // log parameter
    spooler_log.info( 'generate_orders = ' + generate_orders);
 
    // generate orders
    for (i=0;i<generate_orders;i++){
       var order = spooler.create_order();
       order.id = spooler_task.order.id + "_" + i;
       order.params.merge(spooler_task.order.params);
       order.end_state="join";
       if((i%2)==1) {
          order.state="200";
       } else {
          order.state="300";
       }
       jobChain.add_order(order);
    }

    return true;
}
        ]]>
    </script>

    <run_time />
</job>

The Order starts the first Job (generate) in the y_join Job Chain:

The wait Job

The wait Job is configured to read the duration_wait_job parameter and execute a simple script (i.e. ping local host for the length of time specified in the parameter). This script causes the Job to wait for the number of seconds specified in the parameter.

The Orders

The Parent Order

The Parent Order, in this example, with ID main_order has the following 3 parameters:

<?xml version="1.0" encoding="ISO-8859-1"?>
<order >
    <params >
        <param  name="required_orders" value="10"/>
        <param  name="duration_job_a" value="30"/>
        <param  name="generate_orders" value="8"/>
    </params>
    <run_time />
</order>

The Child Orders

The generated Child Orders

Have the ID of the Parent Order (main_order) + "_" + * where * is a string - in the current example simple numbers are used a string.

Have either:

depending on which branch of the Job Chain they should be executed on.

The main_order_add-order Order

Has the ID of the Parent Order (main_order) + "_" + * where * is a string - in the current example "add-order" is used.

This Order is configured with:

<?xml version="1.0" encoding="ISO-8859-1"?>
<order  state="300" end_state="join">
    <run_time />
</order>

Logging

A parameter can be set for the Join Job - show_join_order_list. When this parameter is set to true the all the Child Orders counted by the join job will be listed in the Parent Order log file.

The default setting for this parameter is false.