You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 5 Next »

Scope

The Join Job (JobSchedulerJoinOrders) is used to join up two parallel executing child segments in a Job Chain. It then continues processing 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".

The Join Job can only be used within a Job Chain and is only available for JobScheduler versions 1.11.4 and newer, See the How To Synchronize Job Execution Across Job Chains article for information about synchronizing Jobs in different Job Chains and for joining up parallel executing child Job Chain segments in JobScheduler versions 1.11.3 and older.

Job Chain Patterns

split and join Pattern

The configuration of the Join Job for 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 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 segment.

'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.

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. 

The y_join Job Chain
<?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

The generate_orders Job
<?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";
       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 script that generates 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.

 

.....

The main_order Order
<?xml version="1.0" encoding="ISO-8859-1"?>
<order >
    <params >
        <param  name="required_orders" value="12"/>
        <param  name="wait_time" value="35"/>
        <param  name="generate_orders" value="10"/>
    </params>
    <run_time />
</order>

.....

The main_order_add-order Order
<?xml version="1.0" encoding="ISO-8859-1"?>
<order  state="150" end_state="join">
    <run_time />
</order>

.....

 

  • No labels