Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Article extended

...

Relevant for the current article is that while the Join job is used with the Split Job without any parameters being configured, the Split Job:

  • generates a parameter - required_orders - which is forwarded to the Join Job.

...

  • This parameter defines the number of orders that the Join Job has to receive before processing the main Job Chain continues with processing of the Join Job itself
  • generates an Order for each of the child Job Chain segments that is to be processed in parallel. The end state of each of these Orders is the state of the Join Job.
  • the ID set for each of the child Job Chain segment Orders is made up from the ID of the main Order and state in the Job Chain of the first Job in the child Job Chain segmentsync_state_name:
    This parameter is required for the Job Chain Details view in the JOC Cockpit and for the Job Chain Diagram shown in JOE. It accepts the value of the state that is associated with the join Job node.

'Y' Pattern

The ....following diagram shows the "Y"-pattern Job Chain used in the example download archive that is linked from this article. Note that elements in this pattern have been given particular functions to provide a working example of the Join Job and are not required for its operation in "normal" use.

Flowchart
main
Flowchart
test [label="Order:testmain-order",fillcolor="green"]
100generate [label="100generate",fillcolor="lightskyblue"]
resetadd [label="Order:resetadd-order",fillcolor="green"]
wait [label="wait",fillcolor="lightskyblue"]
150 [label="150",fillcolor="lightskyblue"]
join [label="join",fillcolor="lightskyblue"]
200 [label="200",fillcolor="lightskyblue"]
success [label="success",fillcolor="orange"]

testmain -> 100 generate
100generate -> wait 
resetwait  -> join 
waitadd  -> join150 
150 -> join 
join -> 200 
200 -> success 

Solution

  • Download the example
  • Extract the archive to a folder ./config/live of your JobScheduler Master installation.
  • The archive will extract the files to a folder y_join. 
  • The y_join folder can be renamed if required, the solution does not require the use of specific folder or Job names.

Implementation

The Job Chain, Jobs and Orders

The two "Y" branches in this example and are shown in the pattern diagram above each have a different purpose:

  • The left branch is used by an Order (main_order) that proceeds over the Join Job and Job B to the end of the Job Chain (state: success).
  • The right hand branch is used by an Order (main_order_add-order) that starts at Job A and ends at the Join Job.

To run the example, start the main_order Order. 

Code Block
languagexml
titleThe y_join Job Chain
linenumberstrue
collapsetrue
<?xml version="1.0" encoding="ISO-8859-1"?>
<job_chain  title="Y Join">
    <job_chain_node  state="100" job="generate_orders" next_state="wait" error_state="error"/>
    <job_chain_node  state="150" job="job_a" next_state="join" error_state="error" delay="10"/>
    <job_chain_node  state="wait" job="wait" next_state="join" error_state="error"/>
    <job_chain_node  state="join" job="join" next_state="200" error_state="error"/>
    <job_chain_node  state="200" job="job_b" next_state="success" error_state="error"/>
    <job_chain_node  state="success"/>
    <job_chain_node  state="error"/>
</job_chain>

The demonstration is

Code Block
languagexml
titleThe generate job_create_orders Job
linenumberstrue
collapsetrue
<?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/job_chain_test');/y_join/y_join');

    // log parameter
    spooler_log.info( 'generate_orders = ' + generate_orders);
 
    // generate orders
    for (i=0;i<10i<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";
       order.state="150";
       jobChain.add_order(order);
    }

    return true;
}
        ]]>
    </script>

    <run_time />
</job>

The test Order starts the first Job (job_create_orders) in the job_chain_test Job Chain:

  • this Job contains a shell script that generates 10 the  orders (see line XX of the listing) for the branch of the Job Chain from the job_nix Job to the join Job.

...

As the end_state for the generated Orders is the join Job state, these orders will be registered by the join job and counted towards to the value set by the job_create_orders shell script in the for loop (10)

The Orders

The Main Order

The main Order in this example has 3 parameters:

  • required_orders
    • This parameter (Default 12.)
  • wait_time
    • this is the time in seconds that the Wait Job will wait before the main Order moves to the Join Job. (Default 35 secs.)
    • This parameter is not required by the Join Job.
  • generate_orders
    • this is the number of Orders that are to be generated by the generate_orders Job. (Default 10.) 
    • This parameter is not required by the Join Job.

The Secondary Orders

The main_order_add-order Order

This Order is configured with:

  • state = 150 (the state corresponding to job_a) and
  • end_state = join (the state corresponding to the Join Job) This means that this Order will be registered by the Join Job as counting towards the required orders.

 

.....

Code Block
languagexml
titleThe job_create_orders Jobmain_order Order
linenumberstrue
collapsetrue
<?xml version="1.0" encoding="ISO-8859-1"?>
<job_chain<order >
    <job_chain_node  state="100" job="job_create_orders" next_state="wait" error_state="error"/>
    <job_chain_node  state="150" job="job_a" next_state="join" error_state="error" delay="10"/>
    <job_chain_node  state="wait" job="wait" next_state="join" error_state="error"/>
    <job_chain_node  state="join" job="join" next_state="200" error_state="error"/>
    <job_chain_node  state="200" job="job_b" next_state="success" error_state="error"/>
    <job_chain_node  state="success"/>
    <job_chain_node  state="error"/>
</job_chain>

.....

Code Block
languagexml
titleThe test_add-order Order
linenumberstrue
collapsetrue
<?xml version="1.0" encoding="ISO-8859-1"?>
<order >
    <params >
        <params >
        <param  name="required_orders" value="12"/>
        <param  name="wait_time" value="35"/>
        <param  name="requiredgenerate_orders" value="1210"/>
    </params>
    <run_time />
</order>

...

Code Block
languagexml
titleThe testmain_order_add-order Order
linenumberstrue
collapsetrue
<?xml version="1.0" encoding="ISO-8859-1"?>
<order  state="150" end_state="join">
    <run_time />
</order>

...