Programming patterns

This section describes common patterns for parallel programming using the Compute Grid Parallel Job Manager.

SPI Router Pattern

The Parallel Job Manager design allows for only a single implementation for each SPI per WebSphere profile. This means that all jobs that run on that node use the same SPI implementations. In order to have the custom SPIs on a per-job basis, use the SPI Router Pattern.

To use the SPI Router Pattern that comes with Compute Grid, perform the following steps:
  1. Specify PJM SPI classes in your xd.spi.properties files:

    spi.parallel.Parameterizer=com.ibm.wsspi.batch.router.ParameterizerRouter

    spi.parallel.logicalTX.Synchronization=com.ibm.wsspi.batch.router.SynchronizationRouter

    spi.parallel.status.SubJobAnalyzer=com.ibm.wsspi.batch.router.SubJobAnalyzerRouter

    spi.parallel.status.SubJobCollector=com.ibm.wsspi.batch.router.SubJobCollectorRouter

    Note: The SPI router pattern does not apply to the LifeCycle SPI.
  2. Create an SPI property file for each unique parallel job:

    The file must be created in the $USER_INSTALL_ROOT/properties directory. The file must contain the following keys:

    Parameterizer=<job-specific SPI class>

    Synchronization=<job-specific SPI class>

    SubJobCollector=<job-specific SPI class>

    SubJobAnalyzer=<job-specific SPI class>

  3. Specify job-specific SPI file name in the job step property of the top-level job :

    prop name="PJMRouterAPIs" value=<job-specific SPI properties file name>

  4. In the step implementation, the createJobStep() method sets the BatchAPIs property in the SubJobContext for the rest of the subordinate job SPIs to find:
    import com.ibm.wsspi.batch.router.ContextAccessor;
    public void createJobStep() {
    		// Store the spi properties file in the JobStepContext 
    		// for use throughout this sub-job.
    		// PJM_ROUTER_APIS = "PJMRouterAPIs";
    		String batchJobName = 
    		props.getProperty(PjmRouterConstants.PJM_ROUTER_APIS);
    		ContextAccessor.setBatchAPIsForSubJob(batchJobName);
  5. In the subordinate job application, use the utility methods

    ContextAccessor.setValueInSubJob(String keyName, Object value) and ContextAccessor.getValueFromSubJob(String keyName)

    in place of JobStepContext.setUserData(…)/getUserData() methods.