Problem

Integrate code that is already parallelized and control how many instances of a task the agent runs.

Solution

Set the ExclusiveExecution property on a job to specify only one instance of a task should run concurrently.

Java  Copy imageCopy
package stkscalabilitysdk.howto;


import java.net.InetAddress;
import java.text.SimpleDateFormat;
import java.util.GregorianCalendar;

import agi.parallel.client.ClusterJobScheduler;
import agi.parallel.client.IJobScheduler;
import agi.parallel.client.Job;
import agi.parallel.infrastructure.Task;
import agi.parallel.infrastructure.TaskProperties;

public class ExclusiveExecution {
    public static void main(String[] args) {
        IJobScheduler scheduler = new ClusterJobScheduler("localhost");
        try {
            scheduler.connect();

            Job job = scheduler.createJob();

            // Set ExclusiveExecution to true
            job.setExclusiveExecution(true);

            for (int i = 0; i < 3; ++i) {
                Task task = new OnlyTaskThatIsRunning();
                job.addTask(task);
            }

            job.submit();
            job.waitUntilDone();

            SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss aaa");
            for (int i = 0; i < 3; ++i) {
                GregorianCalendar start = (GregorianCalendar) job.getTasks().get(i).getProperty(TaskProperties.HOST_START_TIME);
                GregorianCalendar end = (GregorianCalendar) job.getTasks().get(i).getProperty(TaskProperties.HOST_END_TIME);

                System.out.println(String.format("Task #%s ran on %s from %s to %s", i + 1, job.getTasks().get(i).getResult(), dateFormat.format(start.getTime()), dateFormat.format(end.getTime())));
            }
        } finally {
            scheduler.dispose();
        }

        /*
         * The output of the application should resemble:
         * Task #1 ran on MyComputerName from 2/28/2013 5:34:24 PM to 2/28/2013 5:34:29 PM
         * Task #2 ran on MyComputerName from 2/28/2013 5:34:29 PM to 2/28/2013 5:34:34 PM
         * Task #3 ran on MyComputerName from 2/28/2013 5:34:34 PM to 2/28/2013 5:34:39 PM
         */
    }

    public static class OnlyTaskThatIsRunning extends Task {
        @Override
        public void execute() {
            try {
                Thread.sleep(5000);
                this.setResult(InetAddress.getLocalHost().getHostName());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

Discussion

In cases where code has already been parallelized and will automatically use all the cores on a single machine, it would be bad for performance if the tasks were run in parallel. In these situations, execute only one instance of the task on each machine at a time. That is, if 8 cores are available on two machines, run only one host at a time on each of the two machines. To do this, set the ExclusiveExecution property to true.

Once the "exclusive" task completes, the agent goes back to the normal state and its cores are available to the cluster again.

See Also