Scenario

  • Orders for job chains can be assigned calendars that specify the date for which an order should be executed, see JOC Cockpit - Calendar Management.
  • Frequently such job chains are executed on a specific date, but should carry a business date parameter - handed over to scripts and executables - that specifies e.g. the previous day.
  • In this situation the execution date is different from the business date and suggests some more complex scenarios:
    • The business date might be specific for a calendar, let's assume Mon-Fri considering non-working days of a stock exchange in some country.
    • The execution date could be specific for a company calendar in a different country that includes to execute jobs Mon-Thu excluding non-working days in that country or company.
    •  Therefore the order for a business date targeted for some Fri would be executed next Mon. Should this Mon meet a non-working day then the execution could be postponed to next Tue. As a result we face a non-deterministic number of days between the business date and the execution date.
  • JobScheduler handles execution dates well, but does not know the distinction from a business date for which some job chain is executed. This article proposes a solution to this gap.

Solution Outline

  • Basically two calendars have to be used
    • a calendar for business dates that are used to parameterize orders for job chains.
    • a calendar for execution dates on which job chains are started.
  • The solution includes to
    • create a standalone job that creates an order for a job chain. The job runs on business dates and will create an order parameter for this date. 
    • create a job chain that is specified to run on execution dates, i.e. is based on its own calendar.
  • As a consequence the following scenarios are covered;
    • two orders for two business dates Thu and Fri are created. If Thu and Fri do not meet execution dates in the company calendar then both orders will wait in the target job chain to be executed e.g. next Mon, each order carrying its individual business date parameter.
    • if one of the scheduled orders fails then this does not prevent other orders for other business dates from being executed.

Implementation

  • The below sample implementation is available for download: business_dates.zip
  • Unzip the sample to your JobScheduler Master's live folder. This will create a business_date sub-folder with the below job-related objects.

Standalone Job to create Orders for Business Dates

The job run_for_business_date is implemented with JavaScript to run for all platforms (could be any other supported scripting language):

Stanalone Job: run_for_business_date
<job  stop_on_error="no" title="Create order for business date">
    <script  language="java:javascript">
        <![CDATA[
function spooler_process()
{
    // for simplification let's assume the name of the target job chain that should be 
    // scheduled is the same as the current job
    var job_chain = spooler.job_chain( spooler_task.job.name );

    // create a new order object
	var order = spooler.create_order();
    // let's assume we copy all task parameters to the order
    order.params = spooler_task.params;
    // then we add the business date parameter which is the job execution date
    var today = Date();
    order.params.set_value( 'business_date', today );
    
    // let's postpone execution for one day
    order.at = "now + 24:00:00";
    // submit the newly created order
    spooler_log.info( '.. scheduling order for business date: ' + today );
    job_chain.add_order( order );

	return false;
}
        ]]>
    </script>
    <run_time >
        <weekdays >
            <day  day="1 2 3 4 5">
                <period  single_start="10:00"/>
            </day>
        </weekdays>
    </run_time>
</job>

Explanations:

  • The comments with the code should be self-explanatory,
  • Consider that a business_date parameter is created that carries the current date.
  • This sample does not make use of a calendar, but directly uses a start-time rule to run on Mon-Fri at 10am.

Job Chain to run on Execution Dates

The job chain run_for_business_date references two jobs job1 and job2.

Job Chain: run_for_business_date
<job_chain>
    <job_chain_node  state="job1" job="job1" next_state="job2" error_state="error" on_error="suspend"/>
    <job_chain_node  state="job2" job="job2" next_state="success" error_state="error" on_error="suspend"/>
    <job_chain_node  state="success"/>
    <job_chain_node  state="error"/>
</job_chain>

Explanations:

  • Consider use of the on_error attribute: in case of error for a job not the job will be stopped, but the order will be suspended. This allows subsequent orders to pass the job node independently from the execution result of a previous order.
  • The second job job2 is not considered as it can implement any type of job execution.

Job to run on Execution Dates

The job job1 is implemented like this:

Job Chain Job: job1
<job  stop_on_error="no" order="yes">
    <script  language="shell">
        <![CDATA[
echo "Job %SCHEDULER_JOB_NAME% running for business date %SCHEDULER_PARAM_BUSINESS_DATE%"
        ]]>
    </script>
    <run_time >
        <weekdays >
            <day  day="1 2 3 4"/>
        </weekdays>
    </run_time>
</job></job_chain>

Explanations:

  • This is the first job of the job chain. It simply echos it's job name and the business_date job parameter. Job syntax is presented for Windows, use $SCHEDULER_JOB_NAME and $SCHEDULER_PARAM_BUSINESS_DATE for Unix environments.
  • This sample does not make use of a calendar, but directly uses a start-time slot to allow execution on Mon-Thu. The start-time slot does not specify a point in time to start the job, but specifies a time-slot that prevents the job from running on any day outside of the time-slot (Mon-Thu). Therefore, if an orders arrives on Fri then this order will wait until Mon to be executed.

Possible Enhancements

  • The above examples are created without use of calendars in order to be compatible with JobScheduler releases before 1.12. Howevev, if you operate a more recent JobScheduler release then we encourage you to use Calendars from the JOC Cockpit that are much more flexible than start-time rules.
  • The above example is not specific for a single job chain. Starting from the assumption that the standalone job run_for_business_date and the job chain carry the same name and are located in the same folder you can create copies of the standalone job to run for any job chain. The assumption of the standalone job is that the execution date should follow the business date (current date) by 24 hours.