Creating a Custom Job

  GigaSpaces 5.X

Documentation Home
Quick Start Guide
Release Notes

Previous release

  Search Here
Searching GigaSpaces Platform 5.X Documentation

                                               

Summary: How to implement a custom Job, Task, and Result using the relevant classes.

The Job Class

Following is an example of a job implementation, PrimeNumberJob. As can be seen, a job class needs to implement the Job interface.

A main method that needs to be implemented as part of the Job interface is split() – this method generates a list of tasks, takes a list of results and aggregates them.

public class PrimeNumberJob implements Job {
    private static final long serialVersionUID = 1L;
    private Identity id;
    private JobDescriptor jobDescriptor;
    private int primeCandidate = -1;
    private int numOfTasks;
    /**
     * Create a PrimNumberJob
     */
    public PrimeNumberJob() {
        id = Identity.newInstance();
    }
    /**
     * @see com.gigaspaces.grid.master.Job#setArguments(Object[])
     */
    public void setArguments(Object[] args) {
        if(args != null && args.length > 0) {
            if(args[0] instanceof String)
                primeCandidate = Integer.valueOf((String)args[0]).intValue();
            else
                throw new IllegalArgumentException("The prime candidate must "+
                                                   "be a String");
        } else {
            throw new IllegalArgumentException("The prime candidate is not " +
                                               "specified");
        }
    }
    /**
     * @see com.gigaspaces.grid.master.Job#split()
     */
    public Task[] split() {
        numOfTasks = getTotalTasks();
        if(numOfTasks==0)
            return(new Task[0]);
        int numbersPerTask = (primeCandidate - 2) / numOfTasks;
        System.out.println("Creating "
                           + numOfTasks
                           + " tasks, "
                           + numbersPerTask
                           + " numbers per task.");
        Task[] result = new Task[numOfTasks];
        for(int i = 0; i < numOfTasks; i++) {
            int startDivisor = i * numbersPerTask + 2;
            int endDivisor = i * numbersPerTask + 2 + numbersPerTask - 1;
            result[i] = new PrimeTask(getIdentity(),
                                             primeCandidate,
                                             startDivisor,
                                             endDivisor);
        }
        return result;
    }
    /**
     * @see com.gigaspaces.grid.master.Job#getTotalTasks()
     */
    public int getTotalTasks() {
        if(primeCandidate == -1)
            throw new IllegalStateException("The job arguments have not been "+
                                            "specified");
        return (int)Math.sqrt((double)primeCandidate - 2);
    }
    /**
     * @see com.gigaspaces.grid.master.Job#getJobDescriptor()
     */
    public JobDescriptor getJobDescriptor() {
        if(jobDescriptor == null) {
            jobDescriptor = new JobDescriptor();
            jobDescriptor.setTitle("Prime Number Cruncher");
            jobDescriptor.setDescription("This job computes if a given integer "+
                                          "is a prime number by dividing the "+
                                          "check process into sub tasks "+
                                          "and utilizing a JavaSpace to coordinate "+
                                          "threads that perform the sub tasks.");
            jobDescriptor.setResultDescription("Result is TRUE if a given integer "
                                                + "is a prime number, otherwise "+
                                                "FALSE");
            jobDescriptor.setArgumentsDescription("The candidate integer number");
            jobDescriptor.setVendor("GigaSpaces");
            jobDescriptor.setVersion("0.1");
        }
        return(jobDescriptor);
    }    
    /**
     * @see com.gigaspaces.grid.master.Job#getIdentity()
     */
    public Identity getIdentity() {
        return(id);
    }
    /**
     * @throws JobException
     * @see com.gigaspaces.grid.master.Job#process(JavaSpace, Transaction, boolean)
     */
    public JobResult process(JavaSpace space,
                             Transaction txn,
                             boolean batch) throws JobException {
        if(space==null)
            throw new NullPointerException("space is null");
        long start = System.currentTimeMillis();
        if(primeCandidate <= 1) {
            long now = System.currentTimeMillis();
            return(new JobResult(new Boolean(false), (now - start)));
        }
        if(primeCandidate == 2) {
            long now = System.currentTimeMillis();
            return(new JobResult(new Boolean(true), (now - start)));
        }
        
        boolean result = true;
        long execTime = -1;
        int numOfResults = 0;
        PrimeResult divisorResult = null;
        PrimeResult template = new PrimeResult(getIdentity());
        System.out.println("Waiting for results, "+
                           "total tasks="+getTotalTasks()+", "+
                           "transaction="+(txn==null?"null":txn.toString()));
        while (numOfResults < getTotalTasks()) {
            try {
                PrimeResult taskResult = (PrimeResult)space.take(template,
                                                                 txn,
                                                                 Long.MAX_VALUE);                         
                numOfResults++;                                    
                if(taskResult.isDivisable()) {
                    divisorResult = taskResult;                
                    result = false;
                    execTime = (long)taskResult.getExecutionTime();
                }
            } catch(Exception e) {
                Throwable cause = (e.getCause()==null?e:e.getCause());
                throw new JobException("Taking PrimeResult entries", cause);
            }            
        }
        if(divisorResult!=null)
            System.out.println("["+numOfResults+"] results tallied, divisor "+
                               divisorResult.m_Divisor.intValue()+" "+
                               "found for "+ primeCandidate);
        else
            System.out.println("["+numOfResults+"] results tallied, no divisor "+
                               "found for "+ primeCandidate);
        if(txn != null) {
            try {
                txn.commit();
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
        long now = System.currentTimeMillis();
        return(new JobResult(new Boolean(result),
                             (execTime==0?(now - start):(execTime))));
    }
}

The Task Class

The task class needs to implement the Task interface. The main method that needs to be implemented as part of this interface is the execute method, which takes a list of arguments wrapped in a Map and returns a TaskResult entry.

public class PrimeTask extends Task {
    private static final long serialVersionUID = 1L;
    public Integer m_ValueToCheck;
    public Integer m_StartDivisor;
    public Integer m_EndDivisor;
    public PrimeTask() {
    }
    /**
     * Create a PrimeTask
     *
     * @param id A non-null {@link com.gigaspaces.grid.master.Identity}
     */
    public PrimeTask(Identity id) {
        super(id);
    }
    /**
     * Create a PrimeTask
     *
     * @param id
     * @param valueToCheck
     * @param startDivisor
     * @param endDivisor
     */
    public PrimeTask(Identity id,
                     int valueToCheck,
                     int startDivisor,
                     int endDivisor) {
        super(id);
        m_ValueToCheck = new Integer(valueToCheck);
        m_StartDivisor = new Integer(startDivisor);
        m_EndDivisor = new Integer(endDivisor);
    }
    /**
     * @see com.gigaspaces.grid.master.Task#execute()
     */
    public TaskResult execute(Map map)  {
        for(int i = m_StartDivisor.intValue();
            i <= m_EndDivisor.intValue();
            i++) {
            /* divisor found */
            if(m_ValueToCheck.intValue() % i == 0) {
                return new PrimeResult(getIdentity(),
                                       m_ValueToCheck.intValue(),
                                       m_StartDivisor.intValue(),
                                       m_EndDivisor.intValue(),
                                       i);
            }
        }
        /* divisor not found */
        return new PrimeResult(getIdentity(),
                               m_ValueToCheck.intValue(),
                               m_StartDivisor.intValue(),
                               m_EndDivisor.intValue(),
                               0);
    }
}

The Result Class

The result is a very simple object that represents the state of a certain task. The identity attribute is used to associate a result with a certain task, and is passed as part of the constructor element.

public class PrimeResult extends TaskResult {
    private static final long serialVersionUID = 1L;
    public Integer m_CheckedValue;
    public Integer m_StartDivisor;
    public Integer m_EndDivisor;
    public Integer m_Divisor;
    /**
     * Create a PrimeResult with no properties
     */
    public PrimeResult() {
    }
    /**
     * Create a PrimeResult
     *
     * @param id The Identity of the PrimeResult
     */
    public PrimeResult(Identity id) {
        super(id);
    }
    /**
     * Create a PrimeResult, setting all properties
     *
     * @param id The Identity of the PrimeResult
     * @param checkedValue
     * @param startDivisor
     * @param endDivisor
     * @param divisor
     */
    public PrimeResult(Identity id,
                       int checkedValue,
                       int startDivisor,
                       int endDivisor,
                       int divisor) {
        super(id);
        m_CheckedValue = new Integer(checkedValue);
        m_StartDivisor = new Integer(startDivisor);
        m_EndDivisor = new Integer(endDivisor);
        m_Divisor = new Integer(divisor);
    }
    /**
     * Get whether the result is prime
     *
     * @return Whether the result is prime
     */
    public boolean isDivisable() {
        return m_Divisor.intValue() != 0;
    }
}

RELATED TOPICS

Compute Grid
Creating a Custom Job
Running Jobs from the Command Line
Spring Parallel Processing Integration
task - Service Grid CLI

Wiki Content Tree


Your Feedback Needed!

We need your help to improve this wiki site. If you have any suggestions or corrections, write to us at techw@gigaspaces.com. Please provide a link to the wiki page you are referring to.

Labels