Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  • The solution implements a job sorter that can be added to the top of any job chain.
    • This job implements a spooler_process() function that suspends all incoming orders.
    • This job is configured for a single task and with an idle timeout attribute, i.e. it executes incoming orders sequentually.
    • Having received the last available order this job waits for the duration specified with the idle_timeout attribute for new orders. 
      • The idle timeout is configured by <job idle_timeout="10"> with the sorter job definition.
      • With the idle timeout being expired this job will execute its spooler_exit() function and will sort and move all orders that have previously been suspended.
        • Sorting is done in alphabetical order.
        • The orders are moved to the next job chain node that follows the sorter job in the job chain.
  • The sample makes use of a job chain job_chain1 that includes the job nodes for the sorter job and a hello job. The job chain accepts Ad Hoc orders that are added by use of JOC and the job chain can easily be modified to watch for incoming files and to create one order for each file.
  • Hint: to re-use the sorter job you can
    • store the job to some central folder and reference the job in individual job chains.
    • move the JavaScript code of the job to come central location and use a corresponding <include> element for individual job scripts.

 

Code Block
languagejs
titleJob sorter
collapsetrue
var jobChainPath = null;
var jobChainNodeState = null;
var jobChainNodeNextState = null;

function spooler_init() {
  spooler_log.info( ".. performing spooler_init()" );

  jobChainPath = spooler_task.order.job_chain.path;
  jobChainNodeState = spooler_task.order.job_chain_node.state;
  jobChainNodeNextState = spooler_task.order.job_chain_node.next_state;

  return true;
}

function spooler_process() {
  var rc = true;

  // suspend all orders, sorting is done on spooler_exit()
  spooler_log.info( ".. suspending current order" );
  spooler_task.order.suspended = true;
  spooler_task.order.state = jobChainNodeState;

  return rc;
}

function spooler_exit() {
  spooler_log.info( ".. peforming spooler_exit()" );
  var rc = true;
  var orderList = Array();

  // select all orders of the current job node
  var response = spooler.execute_xml( "<show_job_chain job_chain='" + jobChainPath + "' what='job_chain_orders'/>" );
  var orderDOM = new Packages.sos.xml.SOSXMLXPath( new java.lang.StringBuffer( response ) );
  var orderNodes = orderDOM.selectNodeList( "/spooler/answer/job_chain/job_chain_node[@state = '" + jobChainNodeState + "']/order_queue/order" );

  // traverse order list and add orders to sort array
  for( orderIndex=0; orderIndex<orderNodes.getLength(); orderIndex++ ) {
    var orderNode = orderNodes.item(orderIndex);
    var orderID = orderDOM.selectSingleNodeValue( orderNode, "@id" );
    if (orderID == null) {
      continue;
    }
    spooler_log.info( ".... order found: " + orderID );
    orderList.push( orderID );
  }

  // alphabetical string sort
  orderList.sort(function(a, b){return (a > b) - (a < b) });
  // numeric sort
  // orderList.sort(function(a, b){return b - a) });

  for(i=0; i<orderList.length; i++) {
    spooler_log.info( ".... moving order: " + orderList[i] );
    var response = spooler.execute_xml( "<modify_order job_chain='" + jobChainPath + "' order='" + orderList[i] + "' state='" + jobChainNodeNextState + "' suspended='no'/>" );
    var orderDOM = new Packages.sos.xml.SOSXMLXPath( new java.lang.StringBuffer( response ) );
    var errorCode = orderDOM.selectSingleNodeValue( "//ERROR/@code" );
    var errorText = orderDOM.selectSingleNodeValue( "//ERROR/@text" );
    if ( errorCode || errorText ) {
      spooler_log.error( "........ modify order state response: errorCode=" + errorCode + ", errorText=" + errorText );
      rc = false;
    }  
  }

  return rc;
}

...